Version developed during Xmas, not tested
authorshort <>
Mon, 28 Jan 2002 22:05:28 +0000 (22:05 +0000)
committershort <>
Mon, 28 Jan 2002 22:05:28 +0000 (22:05 +0000)
 - it should be compatible with current version of sub-package "energie"

.htaccess
config.php
index.php
kewensis-collect.pl

index cc84824..85ae2c3 100644 (file)
--- a/.htaccess
+++ b/.htaccess
@@ -1,4 +1,6 @@
-SourceCharset iso-8859-2
+<IfModule mod_czech.c>
+       SourceCharset utf-8
+</IfModule>
 DirectoryIndex index.php
 php_flag short_open_tag off
 php_flag magic_quotes_gpc off
index 3766162..c2faf91 100644 (file)
@@ -3,11 +3,18 @@
        $admin_mail="short@ucw.cz";
        $cvs_mailhost="vellum.cz";
        $viewcvs=ereg_replace("^/","http://short.vellum.cz/cgi-bin/viewcvs/kewensis/",$HTTP_SERVER_VARS["SCRIPT_NAME"]);
+       $title_prefix="Kewensis";
+       $force_charset="utf-8"; // library texts will be corrupted but who cares
+
+       $limit_max_default=10;
+       $footer_LOCAL=1; // disable remote footer images
 
        $db_host="";
        $db_user="short";
-       $db_pwd_a=file("/home/short/priv/mysql.${db_user}.pwd");
+       $db_pwd_a=@file("/home/short/priv/mysql.${db_user}.pwd");
        $db_pwd=trim($db_pwd_a[0]);
+       if (!$db_pwd) // defaults to $db_pwd=$db_user if no password file found
+               $db_pwd=$db_user;
        $db_name="short";
        $tb_tree="kewensis_tree";
 
index 14f1ff3..12a3190 100644 (file)
--- a/index.php
+++ b/index.php
 
        include("energie/common.php");
 
-       heading(false/*title*/);
+       $head_css="
+.name { font-weight: bold; }
+.PublAuthor { font-variant: small-caps; }
+.Publication { }
+";
+       no_cache();
+
+       $buttonre=".+";
+       prepvar("find"     ,".*"     ,false /* require */);
+       if (isset($find))
+               $find=trim($find);
+       prepvar("confirm"  ,$buttonre,false /* require */);
+       prepvar("delete"   ,$buttonre,false /* require */);
+       prepvar("isolate"  ,$buttonre,false /* require */);
+       prepvar("edit"     ,$buttonre,false /* require */);
+       prepvar("update"   ,$buttonre,false /* require */);
+       prepvar("move"     ,$buttonre,false /* require */);
+       prepvar("reorder"  ,$buttonre,false /* require */);
+       
+       prepvar("move_src","[-0-9 ,]+"    ,isset($move   ) /* require */);
+       prepvar("move_dst","[-0-9]+"      ,isset($move   ) /* require */);
+       prepvar("confirming","[a-z]+"     ,isset($confirm) /* require */);
+       prepvar("reorder_by","[+-]?[0-9]+",isset($reorder) /* require */);
+
+       prepvar("id"     ,"[-0-9]+",(isset($update) || isset($confirm) || isset($delete) || isset($isolate) || isset($edit)) || isset($reorder) /* require */);
+       prepvar("winclose" ,"1",false /* require */);
+
+       // Database fields:
+       prepvar("name"       ,".*"     ,false /* require */);
+       prepvar("PublAuthor" ,".*"     ,false /* require */);
+       prepvar("Publication",".*"     ,false /* require */);
+       prepvar("html"       ,".*"     ,false /* require */);
+
+       // "find" dump limits:
+       prepvar("limit_from","[0-9]*",false /* require */);
+       if (!isset($limit_from))
+               $limit_from=0;
+       prepvar("limit_max" ,"[0-9]*",false /* require */);
+       if (!isset($limit_max))
+               $limit_max=$limit_max_default;
+
+       $permanents_array=array("find","limit_from","limit_max","winclose");
+
+       if (isset($update)) {
+
+function fieldupdate($field)
+{
+       global $cmd,$cmdargnum;
+
+       $cmd.=(!$cmdargnum?" ":",")."$field=";
+       if ($GLOBALS[$field]!="")
+               $cmd.="\"".mysql_escape_string($GLOBALS[$field])."\"";
+       else
+               $cmd.="NULL";
+       $cmdargnum++;
+}
+
+               $cmd="update $tb_tree set";
+               $cmdargnum=0;
+               fieldupdate("name");
+               fieldupdate("PublAuthor");
+               fieldupdate("Publication");
+               fieldupdate("html");
+               $cmd.=" where id=\"".mysql_escape_string($id)."\"";
+               if ($cmdargnum)
+                       db_query($cmd);
+               // PASSTHRU redirect
+               }
+       if (isset($delete)) {
+               db_query("delete from $tb_tree where id=\"".mysql_escape_string($id)."\"");
+               // PASSTHRU redirect
+               }
+       if (isset($isolate)) {
+               $family_id=db_item("select family_id from $tb_tree where id=\"".mysql_escape_string($id)."\"");
+               if ($id!=$family_id)
+                       db_query("update $tb_tree set family_id=id where id=\"".mysql_escape_string($id)."\"");
+               else {
+                       $where="where family_id=\"".mysql_escape_string($family_id)."\" and family_id<>id";
+                       $other_id=db_item("select id from $tb_tree $where limit 1");
+                       db_query("update $tb_tree set family_id=\"".mysql_escape_string($other_id)."\" $where");
+                       }
+               // PASSTHRU redirect
+               }
+       if (isset($move)) {
+               $order=db_item("select max(family_order) from $tb_tree where family_id=\"".mysql_escape_string($move_dst)."\"");
+               foreach(preg_split('/[ ,]/',$move_src,-1,PREG_SPLIT_NO_EMPTY) as $src) {
+                       // UGLY but how to do sequential setting of increasing family_order?
+                       $result=db_query("select id from $tb_tree where family_id=\"".mysql_escape_string($src)."\" order by family_order");
+                       while (($row=mysql_fetch_array($result)))
+                               db_query("update $tb_tree set family_order=\"".(++$order)."\",family_id=\"".mysql_escape_string($move_dst)."\""
+                                               ." where id=\"".mysql_escape_string($row["id"])."\"");
+                       }
+               // PASSTHRU redirect
+               }
+       if (isset($reorder)) {
+               $row=db_array("select family_id,family_order from $tb_tree where id=\"".mysql_escape_string($id)."\"");
+               $other_order=db_item("select family_order from $tb_tree where family_id=\"".mysql_escape_string($row["family_id"])."\""
+                               ." and family_order".($reorder_by<0 ? "<" : ">").$row["family_order"]
+                               ." order by family_order ".($reorder_by<0 ? "desc" : "asc")." limit 1");
+               db_query("update $tb_tree set family_order=family_order".($reorder_by>=0 ? "+" : "").$reorder_by
+                               ." where family_id=\"".mysql_escape_string($row["family_id"])."\""
+                               ." and family_order".($reorder_by<0 ? "<" : ">").$other_order);
+               db_query("update $tb_tree set family_order=".($other_order+$reorder_by)." where id=\"".mysql_escape_string($id)."\"");
+               // PASSTHRU redirect
+               }
 
-       prepvar("find",".+",false /* require */);
+function hiddens($array,$doinputs)
+{
+       global $permanents_array;
+       $r="";
+       foreach ($permanents_array as $key)
+               if (!array_key_exists($key,$array) && isset($GLOBALS[$key]))
+                       $array[$key]=$GLOBALS[$key];
+       foreach ($array as $key=>$val) {
+               if ($doinputs)
+                       $r.="<input type=\"hidden\" name=\"".htmlspecialchars($key)."\" value=\"".htmlspecialchars($val)."\" />\n";
+               else
+                       $r.=($r==""?"?":"&").addpercents($key)."=".addpercents($val);
+               }
+       if (!$doinputs && $r=="")
+               $r="?_dummy=1";
+       return($r);
+}
 
-       if (!isset($find)) {
-               ?>
-<form action="index.php" method="post">
-<input type="text" name="find" size="30" />
-<input type="submit" value="Vyhledat" />
-</form>
+       if (isset($delete) || isset($update) || isset($move) || isset($isolate) || isset($reorder)) {
+               if (isset($winclose)) {
+                       header("Content-type: text/html");
+                       ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs">
+<head><title>Uzavreni okna</title></head>
+<body onload="window.close();">
+<p>Uzavreni okna</p>
+</body></html>
 <?php
-               footer(true /* delimit */);
+                       }
+               else {
+                       // OK: Redirect will NOT keep the request type "POST"!
+                       $redir="http://".$HTTP_SERVER_VARS["HTTP_HOST"].$HTTP_SERVER_VARS["REQUEST_URI"].hiddens(array(),false/*doinputs*/);
+                       header("Location: $redir");
+                       }
                exit();
                }
-       $families=db_query("select distinct family_id from $tb_tree"
-                       ." where name like \"".quotemeta($find)."%\""
-                       ." order by family_id");
 
-function fieldquote($prefix,$field,$class)
+       heading(false/*title*/);
+
+function fieldedit($field,$size,$append="")
 {
        global $row;
+       return("<input type=\"text\" name=\"".htmlspecialchars($field)."\" size=\"$size\" value=\""
+                       .(!isset($row[$field]) ? "" : htmlspecialchars($row[$field]))."\"$append />");
+}
+
+function formconvert($id,$name,$text,$readonly,$anchor,$hiddens=array())
+{
+       global $tb_tree,$row,$winclose;
+       $readonly=(!$readonly ? "" : " readonly=\"readonly\"");
+       if ($winclose)
+               $text.=" (uzavre okno)";
+       $row=db_array("select name,PublAuthor,Publication,html from $tb_tree"
+                       ." where id=\"".mysql_escape_string($id)."\"");
+       $hiddens["id"]=$id;
+       print("<!-- ID=$id -->"
+                       ."<form action=\"index.php$anchor\" method=\"POST\">\n"
+                       ."<table border=\"0\" width=\"100%\"><tr><td align=\"center\"><table border=\"0\"><tr><td>\n"
+                       .fieldedit("name",50,$readonly)
+                       ."\n".fieldedit("PublAuthor",50,$readonly)
+                       ."<br />\n".fieldedit("Publication",100,$readonly)
+                       ."<br /><textarea name=\"html\" rows=\"20\" cols=\"80\">"
+                                       .(!isset($row["html"]) ? "" : htmlspecialchars($row["html"]))
+                                       ."</textarea>\n"
+                       ."</td></tr></table><p>&nbsp;</p>\n"
+                       ."<input type=\"submit\" name=\"".htmlspecialchars($name)."\" value=\"".htmlspecialchars($text)."\" />\n"
+                       .hiddens($hiddens,true/*doinputs*/)
+                       ."</td></tr></table></form>");
+       footer(true /* delimit */);
+}
+
+       if (isset($edit))
+               formconvert($id,"update","Aktualizuj zaznam",false/*readonly*/,"#id_$id");
+       if (isset($confirm) && $confirming=="delete")
+               formconvert($id,$confirming,"Opravdu smazat zaznam?",true/*readonly*/,
+                               "#family_".db_item("select family_id from $tb_tree where id=\"".mysql_escape_string($id)."\""));
+       if (isset($confirm) && $confirming=="isolate")
+               formconvert($id,$confirming,"Opravdu izolovat zaznam?",true/*readonly*/,"#id_$id");
+
+       $reset_from_script="this.form.elements['limit_from'].value=0;";
+       print('<form action="index.php" method="GET">'."\n"
+                       .'<h1 align="center">'
+                       .'<input type="text" name="find" size="40" '
+                                       .(!isset($find)?"":" value=\"".htmlspecialchars($find)."\"")
+                                       ." onkeyup=\"$reset_from_script\" onchange=\"$reset_from_script\" onfocus=\"$reset_from_script\""
+                                       .' />'."\n"
+                       .'&nbsp;<input type="submit" value="Vyhledat" />'."\n"
+                       .'</h1><h2 align="center">'."\n"
+                       .'Prvni skupina: <input type="text" name="limit_from" size="6" value="'.$limit_from.'" />'."\n"
+                       .'&nbsp;&nbsp;&nbsp;'
+                       .'Max skupin: '.'<input type="text" name="limit_max"  size="6" value="'.$limit_max .'" />'."\n"
+                       .'</h2></form>'."\n");
+       if (!isset($find))
+               footer(true /* delimit */);
+       
+       print("<hr />\n");
+
+function fieldquote($prefix,$field,$suffix="")
+{
+       global $row,$fieldquote_tot;
        if (!isset($row[$field]))
-               return "";
-       return $prefix."<span class=\"$class\">".htmlspecialchars($row[$field])."</span>";
+               return("");
+       return($prefix."<span class=\"$field\">".htmlspecialchars($row[$field])."</span>".$suffix);
+}
+
+function formbutton($name,$text,$method="GET",$hidden=array(),$newwin=false,$anchor="")
+{
+       $r="";
+       if ($newwin) {
+               $r.="<table border=\"0\"><tr><td>".formbutton($name,$text,$method,$hidden,false/*newwin*/)."</td><td>";
+               $hidden["winclose"]=1;
+               }
+       $r.=""
+                       ."<form action=\"index.php".($anchor=="" ? "" : "#$anchor")."\" method=\"$method\""
+                                       .(!$newwin ? "" : " target=\"_blank\"").">"
+                       ."<input type=\"submit\" "
+                                       .($name=="" ? "" : " name=\"".htmlspecialchars($name)."\"")
+                                       ." value=\"".htmlspecialchars($newwin ? "(v okne)" : $text)."\" />"
+                       .hiddens($hidden,true/*doinputs*/)
+                       ."</form>";
+
+       if ($newwin)
+               $r.="</td></tr></table>";
+       return($r);
 }
 
-       $family_num=0;
+       $families=db_query("select distinct family_id from $tb_tree"
+                       ." where name like \"".mysql_escape_string($find)."%\""
+                       ." order by name limit $limit_from,".($limit_max+1));
+
+       $arrows="<table border=\"0\" width=\"100%\"><tr><td align=\"center\">\n"
+                       ."<table border=\"0\" width=\"80%\"><tr><td align=\"left\">";
+       if ($limit_from>0)
+               $arrows.=formbutton("","Predchozi","GET",array("limit_from"=>max(0,$limit_from-$limit_max)));
+       $arrows.="</td><td align=\"right\">";
+       if (mysql_num_rows($families)>$limit_max)
+               $arrows.=formbutton("","Dalsi","GET",array("limit_from"=>$limit_from+$limit_max));
+       $arrows.="</td></tr></table></td></tr></table>";
+
+       print "$arrows<hr />\n";
+       $family_tot=0;
        while (($family_row=mysql_fetch_array($families))) {
-               if ($family_num)
+               if ($family_tot)
                        print "<hr />\n";
                $family_id=$family_row["family_id"];
-               $result=db_query("select id,name,Publication,Notes,html from $tb_tree"
+               print("<table border=\"0\" width=\"90%\"><tr><td align=\"right\"><a name=\"family_$family_id\">"
+                               ."<form action=\"index.php#family_$family_id\" method=\"POST\">" // WARNING: <form> will break the line!
+                               ."Skupina&nbsp;c.&nbsp;<input type=\"text\" size=\"10\" readonly=\"readonly\" value=\"$family_id\" />"
+                               ."<br /><br />"
+                                               ."Zaradit do teto skupiny: <input type=\"text\" name=\"move_src\" size=\"21\" value=\"\" />"
+                                               ."&nbsp;<input type=\"submit\" name=\"move\" value=\"Zarad\" />\n"
+                                               .hiddens(array("move_dst"=>$family_id),true/*doinputs*/)
+                                               ."</form>\n"
+                               ."</td></tr></table>\n");
+               $result=db_query("select id,family_order,name,PublAuthor,Publication,html from $tb_tree"
                                ." where family_id=\"$family_id\""
-                               ." order by family_id,family_order");
+                               ." order by family_order");
                $order=0;
                while (($row=mysql_fetch_array($result))) {
-                       if ($order==0)
-                               print "<p>";
-                       elseif ($order==1)
-                               print "<ul>";
                        if ($order>=1)
-                               print "<li>";
+                               print "<blockquote>";
 
-                       print(fieldquote("","name","name")
-                                       .fieldquote("\n","Publ. Author","author")
-                                       .fieldquote("<br />\n","Publication","publication")
-                                       .fieldquote("<br />\n","Notes","notes")
-                                       );
+                       print("<a name=\"id_".$row["id"]."\"><!-- family_order=".$row["family_order"]." --><table border=\"0\" width=\"90%\">");
+
+                       print("<tr><td align=\"left\" valign=\"center\"><table border=\"0\"><tr>");
+                       if ($order>=1) {
+                               print "<td>&bull;</td>";
+                               $tabpfx="<td></td>";
+                               }
+                       else
+                               $tabpfx="";
+                       print("<td>".fieldquote("","name","\n")
+                                       .fieldquote("","PublAuthor")."</td></tr>");
+                       print(fieldquote("<tr>$tabpfx<td>","Publication","</td></tr>"));
                        if (isset($row["html"])) {
                                $import="import: [".$row["id"]."]";
-                               $html=eregi_replace("< */? *a( [^>]*)?>","",$row["html"]);
-                               print("<br />\n<blockquote><!-- BEGIN $import -->\n".$html."\n<!-- END $import --></blockquote>");
+                               $html=$row["html"];
+                               $html=eregi_replace("< *"."/? *a( [^>]*)?>","",$html);
+                               print("<tr>$tabpfx<td><blockquote><!-- BEGIN $import -->\n".$html."\n<!-- END $import --></blockquote></td></tr>");
                                }
-                       print("\n");
+                       print("</table></td><td align=\"right\" valign=\"center\"><table border=\"0\">");
+                       $l="<tr><td align=\"center\">";
+                       $r="</td></tr>";
+                       print(""
+                                       .($order <= 0 ? "" :
+                                                       $l.formbutton("reorder","^^^ Nahoru ^^^","POST",
+                                                                       array("id"=>$row["id"],"reorder_by"=>-1),false/*newwin*/,"family_$family_id").$r)
+                                       .$l.formbutton("confirm","Smaz zaznam"  ,"GET",
+                                                       array("id"=>$row["id"],"confirming"=>"delete"),true/*newwin*/).$r
+                                       .$l.formbutton("edit"   ,"Edituj zaznam","GET",
+                                                       array("id"=>$row["id"]),true/*newwin*/).$r
+                                       .(mysql_num_rows($result)<=1 ? "" :
+                                                       $l.formbutton("confirm","Izoluj zaznam","GET",
+                                                                       array("id"=>$row["id"],"confirming"=>"isolate"),true/*newwin*/).$r)
+                                       .($order+1 >= mysql_num_rows($result) ? "" :
+                                                       $l.formbutton("reorder","vvv Dolu vvv"  ,"POST",
+                                                                       array("id"=>$row["id"],"reorder_by"=>+1),false/*newwin*/,"family_$family_id").$r)
+                                       ."</table></td></tr></table></a>\n"
+                                       );
 
-                       if ($order==0)
-                               print "</p>";
-                       else
-                               print "</li>";
+                       if ($order>=1)
+                               print "</blockquote>";
                        print "\n";
                        $order++;
                        }
+               mysql_free_result($result);
                if ($order>=2)
                        print "</ul>\n";
-               $family_num++;
+               print "</a>\n"; // <a name="family_X"
+               $family_tot++;
+               if ($family_tot >= $limit_max)
+                       break;
                }
-       mysql_free_result($result);
+       mysql_free_result($families);
+       print "<hr />$arrows\n";
 
        footer(false /* delimit */);
 ?>
index 009be1e..61b6d88 100755 (executable)
@@ -7,10 +7,10 @@ use Cwd;
 use Data::Dumper;
 use DBI;
 
-my(%DB,%OWNS,$debugmatch,$D,$key,$owner,$ref,$filename,$doimport,$import_xlate);
+my(%DB,$debugmatch,$D,$key,$owner,$ref,$filename,$doimport,$import_xlate);
 
 %DB=();
-$D=0;
+$D=1;
 $debugmatch=0;
 $doimport=1;
 $import_xlate=1;
@@ -64,7 +64,7 @@ my($file)=@_;
 </head>
 <body bgcolor="#ffffff" text="#000000" link="#006666" vlink="#008080" alink="#008080">
 <HR><b><i>Orchidaceae</i> ($word)</b> ($word) <br>
-((?:<a href="\./PublicationServlet\?id=($id)&query_type=by_id"> ($word)</a> ($word)|$bigword(?:<br>\n$word)*)?<p>($bigword)?</p><p>($word)?</p>(?:
+(?:<a href="\./PublicationServlet\?id=($id)&query_type=by_id"> ($word)</a> ($word)|($bigword(?:<br>\n$word)*))?(<p>($bigword)?</p><p>($word)?</p>(?:
 remarks: .*)?(<HR><h4>Type</h4>)?(<table $any</table>)?(?:
 <h4>Linked Records</h2>
 ((?:$attrpat)*))?(<br>
@@ -83,11 +83,17 @@ remarks: .*)?(<HR><h4>Type</h4>)?(<table $any</table>)?(?:
        my(%rec);
        $rec{"name"}=$1;
        $rec{"Publ. Author"}=$2;
-       $rec{"Publication"}="$5 $6" if defined($5) && defined($6);
-       $rec{"html"}=$3 if defined $3;
-       my($attrsbody)=$11;
+       my $publ="";
+       $publ.="$4 $5" if defined($4) && defined($5);
+       $publ.=$6 if defined $6;
+       $rec{"html"}=$7 if defined $7;
+       my($attrsbody)=$12;
+       # catch-array destroyed here!
+       $publ.=s/\<br\>//g;
+       $rec{"Publication"}=$publ if $publ ne "";
        ($rec{"id"}=$file)=~s#^($id)\.html$#$1#os or failed($file);
        $rec{"html"}=~s#$ipniservletwordthree#<a href="$1/$1$2.html">$3</a>#osg if $import_xlate && exists $rec{"html"};
+       $rec{"refs"}=[];
        my $score=0; # -: upper, +: lower
        while (defined($attrsbody) && $attrsbody=~s%^(?:$attrpat)%%os) {
                # nomenclatural synonym: id=$2
@@ -98,15 +104,15 @@ remarks: .*)?(<HR><h4>Type</h4>)?(<table $any</table>)?(?:
                # later publication: id=$16
                # Is a later publication: id=$18
                my(@refs)=($2,$5,$8,$11,$13,$16,$18);
-               $rec{"refs"}=[];
                while (@refs) {
                        push(@{$rec{"refs"}},$_) if defined ($_=shift @refs);
                        }
-               $score+=-10 if defined  $5; # basionym: id=$5
-               $score+=+10 if defined $13; # Is a basionym: id=$13
-               $score+=+10 if defined $16; # later publication: id=$16
-               $score+=-10 if defined $18; # Is a later publication: id=$18
+               $score+=+10 if defined  $5; # basionym: id=$5
+               $score+=-10 if defined $13; # Is a basionym: id=$13
+               $score+=- 4 if defined $16; # later publication: id=$16
+               $score+=+ 4 if defined $18; # Is a later publication: id=$18
                }
+       $score+=+9 if $rec{"Publ. Author"}=~/^\s*\(/;
        $rec{"score"}=$score;
        if ($attrsbody) {
                failed($file);
@@ -141,18 +147,15 @@ my( $entry )=@_;
        process_file($entry) if -f $entry;
 }
 
-%OWNS=();
-
 foreach (@ARGV)
        { process_entry($_); }
 
-my($id);
-for $id (keys %DB) {
+for my $id (keys %DB) {
        my($refid);
        my(@refs);
        for $refid (@{$DB{$id}{"refs"}}) {
                if (!exists $DB{$refid}) {
-                       warn "Undefined ref id \"$refid\" from id \"$id\"" if $D;
+                       print "Undefined ref id \"$refid\" from id \"$id\"\n" if $D>=1;
                        next;
                        }
                next if $id eq $refid;  # self-ref
@@ -162,28 +165,43 @@ for $id (keys %DB) {
        $DB{$id}{"refs"}=\@refs;
        }
 
-print Data::Dumper->Dump([\%DB],["%DB"]) if $D;
+print Data::Dumper->Dump([\%DB],["%DB"]) if $D>=2;
+
+my %OWNS=map { $_=>$DB{$_}{"refs"}; } keys(%DB);
+my %NAMES=();
 
-%OWNS=map { $_=>[] } keys(%DB);
+for my $id (keys %DB) {
+       $NAMES{$DB{$id}{"name"}}=[] if !exists $NAMES{$DB{$id}{"name"}};
+       push @{$NAMES{$DB{$id}{"name"}}},$id;
+       }
 
-for $id (keys %OWNS) {
+for my $id (keys %DB) {
        next if !exists $OWNS{$id};
-       for my $refid (@{$DB{$id}{"refs"}}) {
+       my @queue=($id,@{$OWNS{$id}});
+       $OWNS{$id}=[];
+       while (my $refid=shift @queue) {
+               if (exists $NAMES{$DB{$refid}{"name"}}) {
+                       push(@queue,@{$NAMES{$DB{$refid}{"name"}}});
+                       delete $NAMES{$DB{$refid}{"name"}};
+                       }
+               next if $refid eq $id;
                next if !exists $OWNS{$refid};
-               push(@{$OWNS{$id}},$refid,@{$OWNS{$refid}});
+               push @queue,@{$OWNS{$refid}};
                delete $OWNS{$refid};
-               print "connected: id=$id,refid=$refid\n" if $D;
+               print "processed connect id=$id <- refid=$refid\n" if $D>=1;
+               push @{$OWNS{$id}},$refid;
                }
        }
 
-print Data::Dumper->Dump([\%OWNS],["%OWNS"]) if $D;
+print Data::Dumper->Dump([\%OWNS],["%OWNS"]) if $D>=2;
 
 foreach $key (keys %OWNS) {
        my(@keys)=@{$OWNS{$key}};
        delete($OWNS{$key});
        unshift(@keys,$key);
-       @keys=sort { $DB{$a}{"score"} <=> $DB{$b}{"score"}
-                       || extract_year($DB{$b}{"Publication"}) <=> extract_year($DB{$a}{"Publication"}); } @keys;
+#      @keys=sort { $DB{$a}{"score"} <=> $DB{$b}{"score"}
+#                      || extract_year($DB{$b}{"Publication"}) <=> extract_year($DB{$a}{"Publication"}); } @keys;
+       @keys=sort { $DB{$a}{"name"} cmp $DB{$b}{"name"}; } @keys;
        my($pkey)=shift(@keys);
        $OWNS{$pkey}=\@keys;
        }
@@ -194,7 +212,8 @@ my($tb_tree);
 $db_driver="mysql";
 $db_host="";
 $db_user="short";
-$DB_PWD=$ENV{"HOME"}."/priv/mysql.${db_user}.pwd";
+#$DB_PWD=$ENV{"HOME"}."/priv/mysql.${db_user}.pwd";
+$db_pwd="short";
 $db_name="short";
 $tb_tree="kewensis_tree";
 
@@ -216,7 +235,6 @@ eval { &db_do("drop table $tb_tree") };
                ."name varchar(100) not null,"
                ."PublAuthor text null,"
                ."Publication text null,"
-               ."Notes text null,"
                ."html text null"
                .")");
 
@@ -224,7 +242,7 @@ eval { &db_do("drop table $tb_tree") };
 &db_do("alter table $tb_tree add index (name)");
 &db_do("alter table $tb_tree add unique (family_id,family_order)");
 
-my $insert_tb_tree=$db->prepare("insert into $tb_tree (id,family_id,family_order,name,PublAuthor,Publication,Notes,html) values (?,?,?,?,?,?,?)")
+my $insert_tb_tree=$db->prepare("insert into $tb_tree (id,family_id,family_order,name,PublAuthor,Publication,html) values (?,?,?,?,?,?,?)")
                or die "Prepare fail: $!";
 
 foreach $owner (sort { $DB{$b}{"name"} cmp $DB{$a}{"name"}; } keys %OWNS) {
@@ -233,9 +251,9 @@ foreach $owner (sort { $DB{$b}{"name"} cmp $DB{$a}{"name"}; } keys %OWNS) {
        my $family_id=$DB{$owner}{"id"};
        for my $family_order (0..$#family) {
                my $id=$family[$family_order];
-               print "insert:$id,".$DB{$id}{"name"}."\n" if $D;
+               print "insert:$id,".$DB{$id}{"name"}."\n" if $D>=2;
                $insert_tb_tree->execute($id,$family_id,$family_order,
-                               $DB{$id}{"name"},$DB{$id}{"Publ. Author"},$DB{$id}{"Publication"},$DB{$id}{"Notes"},$DB{$id}{"html"}
+                               $DB{$id}{"name"},$DB{$id}{"Publ. Author"},$DB{$id}{"Publication"},$DB{$id}{"html"}
                                ) or die "SQL insert failure: $!";
                }
        }