diff --git a/catalog/admin/#user.php# b/catalog/admin/#user.php# new file mode 100644 index 0000000..9c88027 --- /dev/null +++ b/catalog/admin/#user.php# @@ -0,0 +1,76 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_users"); +getstr ("filter"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this user."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("user", "user", "User", SQLCHAR, 80, 240, true); + $f->Text ("login", "login", "Login", SQLCHAR, 80, 240, true); + $f->TextArea ("note", "note", "Note", SQLCHAR, 4, 80, false); + + $f->LoadData ("select * from users where pk = $fk_users"); +} +$f->Hidden ("fk_users"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into users " . $sql)) { + msg ("User added !"); + } else { + error_msg ("Could not add user!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update users set " . $sql . "where pk = $fk_users")) { + msg ("User modified !"); + } else { + error_msg ("Could not modify user !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_users_permissions where fk_users = $fk_users"); + if ($db->Exec ("delete from users where pk = $fk_users")) { + msg ("User deleted !"); + } else { + error_msg ("Could not delete user !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + p ("Back to User"); + } +} else { + $f->Output ($caption, $caption); +} + +p ("Back to User List"); + +pagefooter (); + +?> diff --git a/catalog/admin/.#user.php b/catalog/admin/.#user.php new file mode 120000 index 0000000..5f12a5e --- /dev/null +++ b/catalog/admin/.#user.php @@ -0,0 +1 @@ +gutenbackend@login2.ibiblio.org.27895:1596734584 \ No newline at end of file diff --git a/catalog/admin/.acl.gutenwebprod b/catalog/admin/.acl.gutenwebprod new file mode 100644 index 0000000..3221f43 --- /dev/null +++ b/catalog/admin/.acl.gutenwebprod @@ -0,0 +1,3 @@ + + DirectoryIndex index.php + diff --git a/catalog/admin/a.php b/catalog/admin/a.php new file mode 100644 index 0000000..5f757d0 --- /dev/null +++ b/catalog/admin/a.php @@ -0,0 +1,5 @@ + diff --git a/catalog/admin/alias.php b/catalog/admin/alias.php new file mode 100644 index 0000000..22915b4 --- /dev/null +++ b/catalog/admin/alias.php @@ -0,0 +1,66 @@ +db (); +$db->logger = new logger (); + +getstr ("mode"); +getint ("fk_aliases"); +getint ("fk_authors"); + +$caption = ucfirst ($mode); + +$f = new SQLForm (); + +if (ismode ("add")) { + $f->SQLInject ("fk_authors", "fk_authors", SQLINT); +} +$f->Text ("alias", "alias", "Alias", SQLCHAR, 80, 240, true); + +$f->KeySelect ("alias_heading", "alias_heading", "Heading", SQLINT, 10, 2, false); +$f->last->PushOptions ($titles_heading); +$f->last->ToolTip ("Should this alias generate a user-visible heading?"); + +$f->LoadData ("select * from aliases where pk = $fk_aliases"); + +$f->Hidden ("fk_aliases"); +$f->Hidden ("fk_authors"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this alias. " . + "Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + $retcode = $db->Exec ("insert into aliases " . $sql); + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + $retcode = $db->Exec ("update aliases set " . $sql . "where pk = $fk_aliases"); + } +} +if (isupdatemode ("delete")) { + $retcode = $db->Exec ("delete from aliases where pk = $fk_aliases"); +} + +if (isupdate ()) { + $msg = confirmation_msg ($retcode, $mode, "alias"); + header ("Location: author?mode=edit&fk_authors=$fk_authors&$msg"); + return; +} + +pageheader ("$caption Author Alias"); +$f->Output ($caption, $caption); +pagefooter (); + +?> diff --git a/catalog/admin/alias.php~ b/catalog/admin/alias.php~ new file mode 100644 index 0000000..4e5239a --- /dev/null +++ b/catalog/admin/alias.php~ @@ -0,0 +1,65 @@ +db (); +$db->logger = new logger (); + +getstr ("mode"); +getint ("fk_aliases"); +getint ("fk_authors"); + +$caption = ucfirst ($mode); + +$f = new SQLForm (); + +if (ismode ("add")) { + $f->SQLInject ("fk_authors", "fk_authors", SQLINT); +} +$f->Text ("alias", "alias", "Alias", SQLCHAR, 80, 240, true); + +$f->KeySelect ("alias_heading", "alias_heading", "Heading", SQLINT, 10, 2, false); +$f->last->PushOptions ($titles_heading); +$f->last->ToolTip ("Should this alias generate a user-visible heading?"); + +$f->LoadData ("select * from aliases where pk = $fk_aliases"); + +$f->Hidden ("fk_aliases"); +$f->Hidden ("fk_authors"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this alias. " . + "Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + $retcode = $db->Exec ("insert into aliases " . $sql); + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + $retcode = $db->Exec ("update aliases set " . $sql . "where pk = $fk_aliases"); + } +} +if (isupdatemode ("delete")) { + $retcode = $db->Exec ("delete from aliases where pk = $fk_aliases"); +} + +if (isupdate ()) { + $msg = confirmation_msg ($retcode, $mode, "alias"); + header ("Location: author?mode=edit&fk_authors=$fk_authors&$msg"); + return; +} + +pageheader ("$caption Author Alias"); +$f->Output ($caption, $caption); +pagefooter (); + +?> diff --git a/catalog/admin/attribute.php b/catalog/admin/attribute.php new file mode 100644 index 0000000..2b28663 --- /dev/null +++ b/catalog/admin/attribute.php @@ -0,0 +1,82 @@ +db (); +$db->logger = new logger (); + +getstr ("mode"); +getint ("pk"); +getint ("fk_books"); + +$caption = ucfirst ($mode); + +$f = new SQLForm (); + +if (ismode ("add")) { + $f->SQLInject ("fk_books", "fk_books", SQLINT); +} +$f->KeySelect ("fk_attriblist", "fk_attriblist", "Attribute", SQLINT, 40, 40, true); +$f->last->LoadSQL ("select pk as key, name as caption from attriblist where type = 'unc' order by name"); +$f->last->DefValue (500); +$f->last->ToolTip ("Select an attribute."); + +$f->TextArea ("text", "text", "Value", SQLCHAR, 5, 80, true); +$f->ToolTip ("Enter the value for the selected attribute."); + +$f->Text ("nonfiling", "nonfiling", "Nonfiling Chars", SQLINT, 2, 2, false); +$f->DefValue (0); +$f->ToolTip ("No. of nonfiling characters. eg. 'The Idiot' => 4"); + +$f->Text ("indicators", "indicators", "MARC indicators", SQLCHAR, 2, 2, false); +$f->ToolTip ("MARC indicators (2 digits). See MARC Spec for details. If you are unsure leave blank."); + +$f->KeySelect ("fk_langs", "fk_langs", "Language", SQLCHAR, 40, 40, true); +$f->last->PushOption (null, "undefined"); +$f->last->LoadSQL ("select pk as key, lang as caption from langs order by lang"); +$f->last->DefValue ("en"); +$f->last->ToolTip ("Which language is this attribute in?"); + +$f->LoadData ("select * from attributes where pk = $pk"); + +$f->Hidden ("pk"); +$f->Hidden ("fk_books"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this attribute. " . + "Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + $retcode = $db->Exec ("insert into attributes " . $sql); + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + $retcode = $db->Exec ("update attributes set " . $sql . "where pk = $pk"); + } +} +if (isupdatemode ("delete")) { + $retcode = $db->Exec ("delete from attributes where pk = $pk"); +} + +if (isupdate ()) { + $msg = confirmation_msg ($retcode, $mode, "attribute"); + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ("$caption Attribute"); +p ("A Summary of Commonly Used MARC 21 Fields"); +$f->Output ($caption, $caption); +pagefooter (); + +?> diff --git a/catalog/admin/attribute.php~ b/catalog/admin/attribute.php~ new file mode 100644 index 0000000..e080ff9 --- /dev/null +++ b/catalog/admin/attribute.php~ @@ -0,0 +1,81 @@ +db (); +$db->logger = new logger (); + +getstr ("mode"); +getint ("pk"); +getint ("fk_books"); + +$caption = ucfirst ($mode); + +$f = new SQLForm (); + +if (ismode ("add")) { + $f->SQLInject ("fk_books", "fk_books", SQLINT); +} +$f->KeySelect ("fk_attriblist", "fk_attriblist", "Attribute", SQLINT, 40, 40, true); +$f->last->LoadSQL ("select pk as key, name as caption from attriblist where type = 'unc' order by name"); +$f->last->DefValue (500); +$f->last->ToolTip ("Select an attribute."); + +$f->TextArea ("text", "text", "Value", SQLCHAR, 5, 80, true); +$f->ToolTip ("Enter the value for the selected attribute."); + +$f->Text ("nonfiling", "nonfiling", "Nonfiling Chars", SQLINT, 2, 2, false); +$f->DefValue (0); +$f->ToolTip ("No. of nonfiling characters. eg. 'The Idiot' => 4"); + +$f->Text ("indicators", "indicators", "MARC indicators", SQLCHAR, 2, 2, false); +$f->ToolTip ("MARC indicators (2 digits). See MARC Spec for details. If you are unsure leave blank."); + +$f->KeySelect ("fk_langs", "fk_langs", "Language", SQLCHAR, 40, 40, true); +$f->last->PushOption (null, "undefined"); +$f->last->LoadSQL ("select pk as key, lang as caption from langs order by lang"); +$f->last->DefValue ("en"); +$f->last->ToolTip ("Which language is this attribute in?"); + +$f->LoadData ("select * from attributes where pk = $pk"); + +$f->Hidden ("pk"); +$f->Hidden ("fk_books"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this attribute. " . + "Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + $retcode = $db->Exec ("insert into attributes " . $sql); + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + $retcode = $db->Exec ("update attributes set " . $sql . "where pk = $pk"); + } +} +if (isupdatemode ("delete")) { + $retcode = $db->Exec ("delete from attributes where pk = $pk"); +} + +if (isupdate ()) { + $msg = confirmation_msg ($retcode, $mode, "attribute"); + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ("$caption Attribute"); +p ("A Summary of Commonly Used MARC 21 Fields"); +$f->Output ($caption, $caption); +pagefooter (); + +?> diff --git a/catalog/admin/attribute_list.php b/catalog/admin/attribute_list.php new file mode 100644 index 0000000..ba3becc --- /dev/null +++ b/catalog/admin/attribute_list.php @@ -0,0 +1,39 @@ +db (); +$db->logger = new logger (); + +$db->Exec("select name from attriblist where pk = $attribute"); +$marcfield = $db->Get("name"); +if (!$marcfield) { + pageheader("Usage of ... field"); + + echo("Error: Unrecognized MARC attribute \"$attribute\" given."); + pagefooter(); + return; + } +pageheader ("Usage of $marcfield field"); +$db->Exec("select fk_books, text from attributes " . + "where fk_attriblist = $attribute"); +if ($db->Get("fk_books")) { + echo("\n". + "" . + ""); + do { + $etext=$db->Get("fk_books"); + echo("\n"); + } while ($db->NextRow()); + echo ("
Uses
Etext#Text of MARC field
${etext}" . + $db->Get("text") . "
"); + } else { + echo("MARC field $attribute is unused."); + } +pagefooter(); +?> diff --git a/catalog/admin/attribute_list.php~ b/catalog/admin/attribute_list.php~ new file mode 100644 index 0000000..5547411 --- /dev/null +++ b/catalog/admin/attribute_list.php~ @@ -0,0 +1,38 @@ +db (); +$db->logger = new logger (); + +$db->Exec("select name from attriblist where pk = $attribute"); +$marcfield = $db->Get("name"); +if (!$marcfield) { + pageheader("Usage of ... field"); + + echo("Error: Unrecognized MARC attribute \"$attribute\" given."); + pagefooter(); + return; + } +pageheader ("Usage of $marcfield field"); +$db->Exec("select fk_books, text from attributes " . + "where fk_attriblist = $attribute"); +if ($db->Get("fk_books")) { + echo("\n". + "" . + ""); + do { + $etext=$db->Get("fk_books"); + echo("\n"); + } while ($db->NextRow()); + echo ("
Uses
Etext#Text of MARC field
${etext}" . + $db->Get("text") . "
"); + } else { + echo("MARC field $attribute is unused."); + } +pagefooter(); +?> \ No newline at end of file diff --git a/catalog/admin/attribute_stats.php b/catalog/admin/attribute_stats.php new file mode 100644 index 0000000..36f547c --- /dev/null +++ b/catalog/admin/attribute_stats.php @@ -0,0 +1,42 @@ +db (); +$db->logger = new logger (); + +$marc_fields = array(); +$db->Exec("select pk, name from attriblist order by pk"); +do { + $marc_fields[] = array($db->Get("pk"), $db->Get("name")); + } while ($db->NextRow()); + +echo <<< EOT +

This is a list of all the MARC field/attribute/tag/code names currently +present in the cataloging system. As you can see, we do not actually use +MARC attributes for Author, Language, Subject or LoCC (they are stored +& modified elsewhere), but the system does know about them. This should +probably be fixed. -- Jan 2008

+

Click on the attribute name to get a list of all the uses of it in the system, + along with links to edit them.

+EOT; + +echo("\n". + "" . + ""); +for ($i = 0 ; $i < count($marc_fields); $i++) { + $db->Exec("select count(*) as cnt from attributes where fk_attriblist = " . + $marc_fields[$i][0]); + echo("\n"); + } +echo ("
# of times each MARC field is used in the PG catalog.
MARC field# of entries
" . + $marc_fields[$i][1] . "" . $db->Get("cnt") . + "
"); + +pagefooter(); +?> diff --git a/catalog/admin/attribute_stats.php~ b/catalog/admin/attribute_stats.php~ new file mode 100644 index 0000000..a80a6e8 --- /dev/null +++ b/catalog/admin/attribute_stats.php~ @@ -0,0 +1,41 @@ +db (); +$db->logger = new logger (); + +$marc_fields = array(); +$db->Exec("select pk, name from attriblist order by pk"); +do { + $marc_fields[] = array($db->Get("pk"), $db->Get("name")); + } while ($db->NextRow()); + +echo <<< EOT +

This is a list of all the MARC field/attribute/tag/code names currently +present in the cataloging system. As you can see, we do not actually use +MARC attributes for Author, Language, Subject or LoCC (they are stored +& modified elsewhere), but the system does know about them. This should +probably be fixed. -- Jan 2008

+

Click on the attribute name to get a list of all the uses of it in the system, + along with links to edit them.

+EOT; + +echo("\n". + "" . + ""); +for ($i = 0 ; $i < count($marc_fields); $i++) { + $db->Exec("select count(*) as cnt from attributes where fk_attriblist = " . + $marc_fields[$i][0]); + echo("\n"); + } +echo ("
# of times each MARC field is used in the PG catalog.
MARC field# of entries
" . + $marc_fields[$i][1] . "" . $db->Get("cnt") . + "
"); + +pagefooter(); +?> \ No newline at end of file diff --git a/catalog/admin/author.php b/catalog/admin/author.php new file mode 100644 index 0000000..253910f --- /dev/null +++ b/catalog/admin/author.php @@ -0,0 +1,182 @@ +AddColumn ("$prefix=edit&fk_aliases=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_aliases=#pk#\">Delete", "", "narrow"); + $this->AddSimpleColumn ("alias", "Alias"); + $this->AddSimpleColumn ("c_alias_heading", "Heading", "narrow"); + + $this->AddSubCaption + ("Less prominent names and pseudonyms the author is also known under, " . + "ASCII-fied versions, variant orthographies, common mis-spellings (Gutenburg)."); + } +} + +class ListAuthorUrlsTable extends ListTable { + function __construct () { + global $fk_authors; + $prefix = "AddColumn ("$prefix=edit&fk_author_urls=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_author_urls=#pk#\">Delete", "", "narrow"); + + $this->AddSimpleColumn ("description", "Description"); + $this->AddSimpleColumn ("url", "URL"); + + $this->AddSubCaption ("Interesting sites about the author."); + } +} + +class ListBooksTable extends ListTable { + function __construct () { + $this->AddColumn ("#fk_books#", + "Etext Nr.", "narrow right"); + $this->AddSimpleColumn ("title", "Title"); + $this->AddSimpleColumn ("lang", "Language", "narrow"); + $this->AddSimpleColumn ("role", "Role", "narrow"); + + $this->AddSubCaption ("Books linked to author."); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_authors"); + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_authors where fk_authors = $fk_authors"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + error_msg ("There are still $cnt books related to this author. " . + "You must delete them first."); + } + $db->Exec ("select author from authors where pk = $fk_authors"); + $author = $db->get("author"); + $f->SubCaption ("You are about to delete author: $author."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { +print "









editing

\n"; + $f->SubCaption ("The best-known name or pseudonym and other data."); + $f->Text ("author", "author", "Name", SQLCHAR, 80, 240, true); + $f->ToolTip ("Enter the name or pseudonym the author is best known under. " . + "Put lesser known names or pseudonyms in aliases. " . + "Use full unicode here and put an ASCII-fied version in aliases." . + "(eg. Brontë, Charlotte)"); + + $f->Text ("born_floor", "born_floor", "Born (earliest)", SQLINT, 12, 12, false); + $f->ToolTip ("Year the author was born (earliest estimate). Leave empty if unknown. ". + "(eg. 1803, -250)"); + $f->Text ("born_ceil", "born_ceil", "Born (latest)", SQLINT, 12, 12, false); + $f->ToolTip ("Year the author was born (latest estimate). Leave empty if unknown. ". + "(eg. 1803, -250)"); + + $f->Text ("died_floor", "died_floor", "Died (earliest)", SQLINT, 12, 12, false); + $f->ToolTip ("Year the author died (earliest estimate). Leave empty if unknown. ". + "(eg. 1803, -250)"); + $f->Text ("died_ceil", "died_ceil", "Died (latest)", SQLINT, 12, 12, false); + $f->ToolTip ("Year the author died (latest estimate). Leave empty if unknown. ". + "(eg. 1803, -250)"); + + $f->TextArea ("note", "note", "Note", SQLCHAR, 4, 80, false); + $f->ToolTip ("Any note relevant to the cataloging people."); + $f->LoadData ("select * from authors where pk = $fk_authors"); +} +$f->Hidden ("fk_authors"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into authors " . $sql)) { + msg ("Author added !"); + } else { + error_msg ("Could not add Author!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update authors set " . $sql . "where pk = $fk_authors")) { + msg ("Author modified !"); + } else { + error_msg ("Could not modify author !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from aliases where fk_authors = $fk_authors"); + $db->Exec ("delete from author_urls where fk_authors = $fk_authors"); + if ($db->Exec ("delete from authors where pk = $fk_authors")) { + msg ("Author deleted !"); + $fk_authors = null; + } else { + error_msg ("Could not delete author !"); + } +} + +if (isupdate ()) { + if ($fk_authors) + p ("" . + "Back to Author"); +} else { + + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + $db->exec ("select * from authors where pk = $fk_authors"); + if ($db->FirstRow ()) { + $author_from = $db->Get ("author", SQLCHAR); + p ("Transfer Books"); + } + + p("" . + "Delete Author"); + $db->exec ("select * from aliases where fk_authors = $fk_authors;"); + $db->calcfields ["c_alias_heading"] = new CalcFieldAliasHeading (); + $table = new ListAliasesTable (); + $table->PrintTable ($db, "Aliases"); + + $db->exec ("select * from author_urls where fk_authors = $fk_authors;"); + $table = new ListAuthorUrlsTable (); + $table->PrintTable ($db, "URLs"); + + $db->exec ("select * from v_books where fk_authors = $fk_authors order by title;"); + $table = new ListBooksTable (); + $table->PrintTable ($db, "Books"); + } +} + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/author.php~ b/catalog/admin/author.php~ new file mode 100644 index 0000000..7fe9aea --- /dev/null +++ b/catalog/admin/author.php~ @@ -0,0 +1,181 @@ +AddColumn ("$prefix=edit&fk_aliases=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_aliases=#pk#\">Delete", "", "narrow"); + $this->AddSimpleColumn ("alias", "Alias"); + $this->AddSimpleColumn ("c_alias_heading", "Heading", "narrow"); + + $this->AddSubCaption + ("Less prominent names and pseudonyms the author is also known under, " . + "ASCII-fied versions, variant orthographies, common mis-spellings (Gutenburg)."); + } +} + +class ListAuthorUrlsTable extends ListTable { + function __construct () { + global $fk_authors; + $prefix = "AddColumn ("$prefix=edit&fk_author_urls=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_author_urls=#pk#\">Delete", "", "narrow"); + + $this->AddSimpleColumn ("description", "Description"); + $this->AddSimpleColumn ("url", "URL"); + + $this->AddSubCaption ("Interesting sites about the author."); + } +} + +class ListBooksTable extends ListTable { + function __construct () { + $this->AddColumn ("#fk_books#", + "Etext Nr.", "narrow right"); + $this->AddSimpleColumn ("title", "Title"); + $this->AddSimpleColumn ("lang", "Language", "narrow"); + $this->AddSimpleColumn ("role", "Role", "narrow"); + + $this->AddSubCaption ("Books linked to author."); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_authors"); + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_authors where fk_authors = $fk_authors"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + error_msg ("There are still $cnt books related to this author. " . + "You must delete them first."); + } + $db->Exec ("select author from authors where pk = $fk_authors"); + $author = $db->get("author"); + $f->SubCaption ("You are about to delete author: $author."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { +print "









editing

\n"; + $f->SubCaption ("The best-known name or pseudonym and other data."); + $f->Text ("author", "author", "Name", SQLCHAR, 80, 240, true); + $f->ToolTip ("Enter the name or pseudonym the author is best known under. " . + "Put lesser known names or pseudonyms in aliases. " . + "Use full unicode here and put an ASCII-fied version in aliases." . + "(eg. Brontë, Charlotte)"); + + $f->Text ("born_floor", "born_floor", "Born (earliest)", SQLINT, 12, 12, false); + $f->ToolTip ("Year the author was born (earliest estimate). Leave empty if unknown. ". + "(eg. 1803, -250)"); + $f->Text ("born_ceil", "born_ceil", "Born (latest)", SQLINT, 12, 12, false); + $f->ToolTip ("Year the author was born (latest estimate). Leave empty if unknown. ". + "(eg. 1803, -250)"); + + $f->Text ("died_floor", "died_floor", "Died (earliest)", SQLINT, 12, 12, false); + $f->ToolTip ("Year the author died (earliest estimate). Leave empty if unknown. ". + "(eg. 1803, -250)"); + $f->Text ("died_ceil", "died_ceil", "Died (latest)", SQLINT, 12, 12, false); + $f->ToolTip ("Year the author died (latest estimate). Leave empty if unknown. ". + "(eg. 1803, -250)"); + + $f->TextArea ("note", "note", "Note", SQLCHAR, 4, 80, false); + $f->ToolTip ("Any note relevant to the cataloging people."); + $f->LoadData ("select * from authors where pk = $fk_authors"); +} +$f->Hidden ("fk_authors"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into authors " . $sql)) { + msg ("Author added !"); + } else { + error_msg ("Could not add Author!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update authors set " . $sql . "where pk = $fk_authors")) { + msg ("Author modified !"); + } else { + error_msg ("Could not modify author !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from aliases where fk_authors = $fk_authors"); + $db->Exec ("delete from author_urls where fk_authors = $fk_authors"); + if ($db->Exec ("delete from authors where pk = $fk_authors")) { + msg ("Author deleted !"); + $fk_authors = null; + } else { + error_msg ("Could not delete author !"); + } +} + +if (isupdate ()) { + if ($fk_authors) + p ("" . + "Back to Author"); +} else { + + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + $db->exec ("select * from authors where pk = $fk_authors"); + if ($db->FirstRow ()) { + $author_from = $db->Get ("author", SQLCHAR); + p ("Transfer Books"); + } + + p("" . + "Delete Author"); + $db->exec ("select * from aliases where fk_authors = $fk_authors;"); + $db->calcfields ["c_alias_heading"] = new CalcFieldAliasHeading (); + $table = new ListAliasesTable (); + $table->PrintTable ($db, "Aliases"); + + $db->exec ("select * from author_urls where fk_authors = $fk_authors;"); + $table = new ListAuthorUrlsTable (); + $table->PrintTable ($db, "URLs"); + + $db->exec ("select * from v_books where fk_authors = $fk_authors order by title;"); + $table = new ListBooksTable (); + $table->PrintTable ($db, "Books"); + } +} + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/author_url.php b/catalog/admin/author_url.php new file mode 100644 index 0000000..c3551bb --- /dev/null +++ b/catalog/admin/author_url.php @@ -0,0 +1,72 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_author_urls"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this URL."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + if (ismode ("add")) { + $f->SQLInject ("fk_authors", "fk_authors", SQLINT); + } + $f->Text ("description", "description", "Description", SQLCHAR, 80, 240, true); + $f->Text ("url", "url", "URL", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from author_urls where pk = $fk_author_urls"); +} +$f->Hidden ("fk_author_urls"); +$f->Hidden ("fk_authors"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into author_urls " . $sql)) { + msg ("Author URL added !"); + } else { + error_msg ("Could not add author URL!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update author_urls set " . $sql . "where pk = $fk_author_urls")) { + msg ("Author URL modified !"); + } else { + error_msg ("Could not modify author URL !"); + } + } +} +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from author_urls where pk = $fk_author_urls")) { + msg ("Author URL deleted !"); + } else { + error_msg ("Could not delete author URL !"); + } +} + +if (isupdate ()) { + getint ("fk_authors"); + echo ("

Back to Author

\n\n"); +} else { + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/author_url.php~ b/catalog/admin/author_url.php~ new file mode 100644 index 0000000..f5b4064 --- /dev/null +++ b/catalog/admin/author_url.php~ @@ -0,0 +1,71 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_author_urls"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this URL."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + if (ismode ("add")) { + $f->SQLInject ("fk_authors", "fk_authors", SQLINT); + } + $f->Text ("description", "description", "Description", SQLCHAR, 80, 240, true); + $f->Text ("url", "url", "URL", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from author_urls where pk = $fk_author_urls"); +} +$f->Hidden ("fk_author_urls"); +$f->Hidden ("fk_authors"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into author_urls " . $sql)) { + msg ("Author URL added !"); + } else { + error_msg ("Could not add author URL!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update author_urls set " . $sql . "where pk = $fk_author_urls")) { + msg ("Author URL modified !"); + } else { + error_msg ("Could not modify author URL !"); + } + } +} +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from author_urls where pk = $fk_author_urls")) { + msg ("Author URL deleted !"); + } else { + error_msg ("Could not delete author URL !"); + } +} + +if (isupdate ()) { + getint ("fk_authors"); + echo ("

Back to Author

\n\n"); +} else { + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/authors_list.php b/catalog/admin/authors_list.php new file mode 100644 index 0000000..0f9966b --- /dev/null +++ b/catalog/admin/authors_list.php @@ -0,0 +1,74 @@ +AddColumn ("Edit", + "Add", "narrow"); + $this->AddColumn ("Delete", + "", "narrow"); + if ($fk_authors_from) { + $this->AddColumn ("Transfer To", + "", "narrow"); + $this->TitleColumn ("Transfer all books linked to $author_from to this one."); + } else { + $this->AddColumn ("Transfer From", + "", "narrow"); + $this->TitleColumn ("Transfer all books linked to this author to a different one."); + } + $this->AddSimpleColumn ("author", "Name"); + $this->AddSimpleColumn ("cnt_books", "No. of Books", "narrow right"); + $this->AddSimpleColumn ("born_floor", "Born", "narrow right"); + $this->AddSimpleColumn ("died_floor", "Died", "narrow right"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the authors name (at least one). +Search is case-insensitive. +Use * as wildcard. (eg. Moli*re) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_hidden ("fk_authors_from", $fk_authors_from); +form_hidden ("author_from", $author_from); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $sql_filter = str_replace ('*', '%', $filter); + $sql_filter = $db->f ("$sql_filter%", SQLCHAR); + $db->exec ("select *, (select count (*) from mn_books_authors where fk_authors = authors.pk) as cnt_books from authors where " . + "(author ilike $sql_filter or authors.pk in " . + "(select fk_authors from aliases where alias ilike $sql_filter)) " . + "order by author"); + $table = new ListAuthorsTable (); + $table->PrintTable ($db, $caption, "pgdbfiles"); +} + +pagefooter (); + +?> diff --git a/catalog/admin/authors_list.php~ b/catalog/admin/authors_list.php~ new file mode 100644 index 0000000..47a4bcf --- /dev/null +++ b/catalog/admin/authors_list.php~ @@ -0,0 +1,73 @@ +AddColumn ("Edit", + "Add", "narrow"); + $this->AddColumn ("Delete", + "", "narrow"); + if ($fk_authors_from) { + $this->AddColumn ("Transfer To", + "", "narrow"); + $this->TitleColumn ("Transfer all books linked to $author_from to this one."); + } else { + $this->AddColumn ("Transfer From", + "", "narrow"); + $this->TitleColumn ("Transfer all books linked to this author to a different one."); + } + $this->AddSimpleColumn ("author", "Name"); + $this->AddSimpleColumn ("cnt_books", "No. of Books", "narrow right"); + $this->AddSimpleColumn ("born_floor", "Born", "narrow right"); + $this->AddSimpleColumn ("died_floor", "Died", "narrow right"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the authors name (at least one). +Search is case-insensitive. +Use * as wildcard. (eg. Moli*re) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_hidden ("fk_authors_from", $fk_authors_from); +form_hidden ("author_from", $author_from); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $sql_filter = str_replace ('*', '%', $filter); + $sql_filter = $db->f ("$sql_filter%", SQLCHAR); + $db->exec ("select *, (select count (*) from mn_books_authors where fk_authors = authors.pk) as cnt_books from authors where " . + "(author ilike $sql_filter or authors.pk in " . + "(select fk_authors from aliases where alias ilike $sql_filter)) " . + "order by author"); + $table = new ListAuthorsTable (); + $table->PrintTable ($db, $caption, "pgdbfiles"); +} + +pagefooter (); + +?> diff --git a/catalog/admin/authors_transfer.php b/catalog/admin/authors_transfer.php new file mode 100644 index 0000000..b29939c --- /dev/null +++ b/catalog/admin/authors_transfer.php @@ -0,0 +1,75 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_authors_from"); +getint ("fk_authors_to"); + +if (!$fk_authors_from) error_msg ("No From Author"); +if (!$fk_authors_to) error_msg ("No To Author"); +// don't test for author equality, transferring to the same author +// can be useful to batch-change the role. +// if ($fk_authors_to == $fk_authors_from) error_msg ("But that is the same author!"); + +if (!isupdate ()) { + $db->Exec ("select count (*) as cnt from mn_books_authors where fk_authors = $fk_authors_from"); + $cnt = $db->get ("cnt"); + $f->SQLSelect ("fk_roles", "fk_roles", "Author Role", SQLCHAR, 40, 40, true, + "select 'same' as value, 'Same Role' as caption union " . + "select pk as value, role as caption from roles order by caption"); + $f->SetFieldData ("fk_roles", "same"); + $f->SubCaption ("You are about to transfer $cnt books from $author_from to $author_to."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} + +$f->Hidden ("fk_authors_from"); +$f->Hidden ("fk_authors_to"); +$f->Hidden ("author_from"); +$f->Hidden ("author_to"); + +if (isupdate ()) { + getstr ("fk_roles"); + if ($fk_roles == "same") { + $sql = "update mn_books_authors set fk_authors = $fk_authors_to " . + "where fk_authors = $fk_authors_from"; + } else { + $sql_fk_roles = $db->f ($fk_roles, SQLCHAR); + $sql = "update mn_books_authors set fk_authors = $fk_authors_to, fk_roles = $sql_fk_roles " . + "where fk_authors = $fk_authors_from"; + } + if ($db->exec ($sql)) { + msg ("Books transferred !"); + } else { + error_msg ("Could not transfer books !"); + } + p ("Delete From Author ($author_from)"); + p ("Back to To Author ($author_to)"); +} else { + $f->Output ($caption, $caption); +} + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> + diff --git a/catalog/admin/authors_transfer.php~ b/catalog/admin/authors_transfer.php~ new file mode 100644 index 0000000..af7fe40 --- /dev/null +++ b/catalog/admin/authors_transfer.php~ @@ -0,0 +1,74 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_authors_from"); +getint ("fk_authors_to"); + +if (!$fk_authors_from) error_msg ("No From Author"); +if (!$fk_authors_to) error_msg ("No To Author"); +// don't test for author equality, transferring to the same author +// can be useful to batch-change the role. +// if ($fk_authors_to == $fk_authors_from) error_msg ("But that is the same author!"); + +if (!isupdate ()) { + $db->Exec ("select count (*) as cnt from mn_books_authors where fk_authors = $fk_authors_from"); + $cnt = $db->get ("cnt"); + $f->SQLSelect ("fk_roles", "fk_roles", "Author Role", SQLCHAR, 40, 40, true, + "select 'same' as value, 'Same Role' as caption union " . + "select pk as value, role as caption from roles order by caption"); + $f->SetFieldData ("fk_roles", "same"); + $f->SubCaption ("You are about to transfer $cnt books from $author_from to $author_to."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} + +$f->Hidden ("fk_authors_from"); +$f->Hidden ("fk_authors_to"); +$f->Hidden ("author_from"); +$f->Hidden ("author_to"); + +if (isupdate ()) { + getstr ("fk_roles"); + if ($fk_roles == "same") { + $sql = "update mn_books_authors set fk_authors = $fk_authors_to " . + "where fk_authors = $fk_authors_from"; + } else { + $sql_fk_roles = $db->f ($fk_roles, SQLCHAR); + $sql = "update mn_books_authors set fk_authors = $fk_authors_to, fk_roles = $sql_fk_roles " . + "where fk_authors = $fk_authors_from"; + } + if ($db->exec ($sql)) { + msg ("Books transferred !"); + } else { + error_msg ("Could not transfer books !"); + } + p ("Delete From Author ($author_from)"); + p ("Back to To Author ($author_to)"); +} else { + $f->Output ($caption, $caption); +} + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> + diff --git a/catalog/admin/book-make-fileinfo.php b/catalog/admin/book-make-fileinfo.php new file mode 100644 index 0000000..010596a --- /dev/null +++ b/catalog/admin/book-make-fileinfo.php @@ -0,0 +1,78 @@ +FirstRow ()) { + do { + $v = $db->get ("value", SQLCHAR); + echo ("$caption: $v\n"); + } while ($db->NextRow ()); + } +} + +$db = $config->db (); + +$db->exec ("select * from books where pk = $fk_books"); +if (!$db->FirstRow ()) { + exit (); +} + +$release_date = $db->get ("release_date", SQLDATE); +$copyrighted = $db->get ("copyrighted", SQLINT); +echo ("Etext-Nr: $fk_books\n"); +echo ("Release-Date: " . date ("M d, Y\n", $release_date)); +echo ("Copyrighted: $copyrighted\n"); + +$db->exec ("select author, role from v_books_authors " . + "where fk_books = $fk_books"); +if ($db->FirstRow ()) { + do { + $author = $db->get ("author", SQLCHAR); + $role = $db->get ("role", SQLCHAR); + echo ("$role: $author\n"); + } while ($db->NextRow ()); +} + +$db->exec ("select title as value from titles where title_order = 1 and fk_books = $fk_books"); +output ($db, "Title"); + +$db->exec ("select title as value from titles where title_order = 2 and fk_books = $fk_books"); +output ($db, "Alternate Title"); + +$db->exec ("select title as value from titles where title_order = 3 and fk_books = $fk_books"); +output ($db, "Contents"); + +$db->exec ("select note as value from notes where fk_books = $fk_books"); +output ($db, "Note"); + +$db->exec ("select lang as value from langs, mn_books_langs " . + "where langs.pk = fk_langs and fk_books = $fk_books"); +output ($db, "Language"); + +$db->exec ("select pk as value from loccs, mn_books_loccs " . + "where loccs.pk = fk_loccs and fk_books = $fk_books"); +output ($db, "Locc"); + +$db->exec ("select subject as value from subjects, mn_books_subjects " . + "where subjects.pk = fk_subjects and fk_books = $fk_books"); +output ($db, "Subject"); + +$db->exec ("select category as value from categories, mn_books_categories " . + "where categories.pk = fk_categories and fk_books = $fk_books"); +output ($db, "Category"); + +echo ("----------\n"); + +?> diff --git a/catalog/admin/book-make-fileinfo.php~ b/catalog/admin/book-make-fileinfo.php~ new file mode 100644 index 0000000..08c55bd --- /dev/null +++ b/catalog/admin/book-make-fileinfo.php~ @@ -0,0 +1,77 @@ +FirstRow ()) { + do { + $v = $db->get ("value", SQLCHAR); + echo ("$caption: $v\n"); + } while ($db->NextRow ()); + } +} + +$db = $config->db (); + +$db->exec ("select * from books where pk = $fk_books"); +if (!$db->FirstRow ()) { + exit (); +} + +$release_date = $db->get ("release_date", SQLDATE); +$copyrighted = $db->get ("copyrighted", SQLINT); +echo ("Etext-Nr: $fk_books\n"); +echo ("Release-Date: " . date ("M d, Y\n", $release_date)); +echo ("Copyrighted: $copyrighted\n"); + +$db->exec ("select author, role from v_books_authors " . + "where fk_books = $fk_books"); +if ($db->FirstRow ()) { + do { + $author = $db->get ("author", SQLCHAR); + $role = $db->get ("role", SQLCHAR); + echo ("$role: $author\n"); + } while ($db->NextRow ()); +} + +$db->exec ("select title as value from titles where title_order = 1 and fk_books = $fk_books"); +output ($db, "Title"); + +$db->exec ("select title as value from titles where title_order = 2 and fk_books = $fk_books"); +output ($db, "Alternate Title"); + +$db->exec ("select title as value from titles where title_order = 3 and fk_books = $fk_books"); +output ($db, "Contents"); + +$db->exec ("select note as value from notes where fk_books = $fk_books"); +output ($db, "Note"); + +$db->exec ("select lang as value from langs, mn_books_langs " . + "where langs.pk = fk_langs and fk_books = $fk_books"); +output ($db, "Language"); + +$db->exec ("select pk as value from loccs, mn_books_loccs " . + "where loccs.pk = fk_loccs and fk_books = $fk_books"); +output ($db, "Locc"); + +$db->exec ("select subject as value from subjects, mn_books_subjects " . + "where subjects.pk = fk_subjects and fk_books = $fk_books"); +output ($db, "Subject"); + +$db->exec ("select category as value from categories, mn_books_categories " . + "where categories.pk = fk_categories and fk_books = $fk_books"); +output ($db, "Category"); + +echo ("----------\n"); + +?> \ No newline at end of file diff --git a/catalog/admin/book.php b/catalog/admin/book.php new file mode 100644 index 0000000..4577455 --- /dev/null +++ b/catalog/admin/book.php @@ -0,0 +1,336 @@ +AddColumn ("$prefix=edit&pk=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&pk=#pk#\">Delete", "", "narrow"); + + $this->AddSimpleColumn ("name", "MARC Tag"); + $this->AddSimpleColumn ("indicators", "MARC Indicators", "narrow"); + $this->AddSimpleColumn ("nonfiling", "Nonfiling Chars", "narrow"); + $this->AddSimpleColumn ("text", "Text"); + } +} + +class ListMarcFieldsTable extends ListTable { + function __construct () { + global $fk_books, $fk_marcauthrecs; + $prefix = "AddColumn ("$prefix=delete&fk_marcauthrecs=#fk_marcauthrecs#&fk_marctags=#fk_marctags#\">Unlink", + "", "narrow"); + // $this->AddColumn ("$prefix=edit&fk_marcauthrecs=#fk_marcauthrecs#&fk_marctags=#fk_marctags#\">Edit Link", "", "narrow"); + + $this->AddSimpleColumn ("name", "MARC Tag"); + // $this->AddSimpleColumn ("indicators", "MARC Indicators", "narrow"); + // $this->AddSimpleColumn ("nonfiling", "Nonfiling Chars", "narrow"); + $this->AddSimpleColumn ("text", "Text"); + } +} + +class ListAuthorsTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_authors=#pk#&fk_roles=#fk_roles#\">Unlink", + "Link", + "narrow"); + $this->AddColumn ("$prefix=edit&fk_authors=#pk#&fk_roles=#fk_roles#\">Edit Link", + "", "narrow"); + $this->AddColumn ("#author#", "Author"); + $this->AddSimpleColumn ("role", "Role", "narrow"); + $this->AddSimpleColumn ("c_heading", "Heading", "narrow"); + $this->AddSimpleColumn ("born_floor", "Born", "narrow right"); + $this->AddSimpleColumn ("died_floor", "Died", "narrow right"); + + $this->AddSubCaption ("All authors for this work."); + } +} + +class ListReviewsTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddSubCaption ("All reviews for this work."); + + $prefix = "AddColumn ("$prefix=edit&fk_reviews=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_reviews=#pk#\">Delete", "", "narrow"); + + $this->AddSimpleColumn ("name", "Reviewer"); + $this->AddSimpleColumn ("review", "Review"); + } +} + +class ListCategoriesTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_categories=#pk#\">Unlink", + "$prefix=add\">Link", "narrow"); + + $this->AddSimpleColumn ("category", "Category"); + + $this->AddSubCaption ("All categories for this work."); + } +} + +class ListSubjectsTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_subjects=#pk#\">Unlink", + "$prefix=add\">Link", "narrow"); + + $this->AddColumn ("#subject#", "Subject"); + //Make the subject name's clickable links to the edit & list of books page + + $this->AddColumn ("#pk#", "#", "narrow"); + //List the Internal Code #. + + $this->AddSubCaption ("All subjects for this work."); + } +} + +class ListLangsTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_langs=#pk#\">Unlink", + "$prefix=add\">Link", "narrow"); + + $this->AddSimpleColumn ("lang", "Language"); + + $this->AddSubCaption ("Languages of all major sections in this work."); + } +} + +class ListLoccsTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_loccs=#pk#\">Unlink", + "$prefix=add\">Link", "narrow"); + $this->AddSimpleColumn("pk", "Code"); + $this->AddSimpleColumn ("locc", "LoC class"); + + $this->AddSubCaption ("All LoC Classes this work falls into."); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_books"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this book."); + $f->SubCaption ("Press the '$caption' button to continue or hit " . + "the back button on your browser to dismiss."); +} else { + $f->Text ("pk", "pk", "EText Nr.", SQLINT, 20, 5, true); + $f->ToolTip ("Enter the ebook number."); + $f->Text ("release_date", "release_date", "Release Date", SQLCHAR, 20, 20, false); + $f->ToolTip ("Enter the official release date."); + $f->CheckBox ("copyrighted", "copyrighted", "Copyrighted", SQLINT); + $f->ToolTip ("Check if book is copyrighted."); + $f->CheckBox ("updatemode", "updatemode", "Manual Update", SQLINT); + $f->ToolTip ("Check if book is manually updated."); + + $f->LoadData ("select * from books where pk = $fk_books"); +} +$f->Hidden ("fk_books"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into books " . $sql)) { + msg ("Book added !"); + } else { + error_msg ("Could not add Book!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + // set manually updated mode + if ($db->Exec ("update books set " . $sql . "where pk = $fk_books")) { + msg ("Book modified !"); + } else { + error_msg ("Could not modify book !"); + } + } +} +if (isupdatemode ("delete")) { + $db->exec ("delete from files where fk_books = $fk_books"); + $db->exec ("delete from attributes where fk_books = $fk_books"); + $db->exec ("delete from reviews.reviews where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_authors where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_langs where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_loccs where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_subjects where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_categories where fk_books = $fk_books"); + if ($db->Exec ("delete from books where pk = $fk_books")) { + msg ("Book deleted !"); + } else { + error_msg ("Could not delete book !"); + } +} + +if (isupdate ()) { + getint ("fk_books"); + echo ("

Back to Book

\n\n"); +} else { + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + + p ("Goto Edit Files Page — " . + "etext/${fk_books}#bibrec\">Goto Bibrec Page — " . + "etext/${fk_books}#download\">Goto Bibrec Download Page"); + + $db->exec ("select gutindex from books where pk = $fk_books"); + if ($db->FirstRow ()) { + $gutindex = $db->get ("gutindex", SQLCHAR); + if (!empty ($gutindex)) { + echo ("
$gutindex
\n"); + } + } + + // Authors for book + $db->exec ("select authors.pk as pk, author, heading, born_floor, died_floor, " . + "fk_roles, role " . + "from authors, mn_books_authors, roles " . + "where authors.pk = mn_books_authors.fk_authors " . + "and mn_books_authors.fk_roles = roles.pk " . + "and mn_books_authors.fk_books = $fk_books " . + "order by author;"); + $db->calcfields ["c_heading"] = new CalcFieldHeading (); + $table = new ListAuthorsTable (); + $table->PrintTable ($db, "Authors", "pgdbdata"); + + p ("A Summary of Commonly Used MARC 21 Fields"); + + // Uncontrolled Fields for book + $db->exec ("select attributes.*, attriblist.name from attributes, attriblist " . + "where attributes.fk_books = $fk_books and " . + "attributes.fk_attriblist = attriblist.pk " . + "order by attriblist.name;"); + $table = new ListAttributesTable (); + $table->PrintTable ($db, "Uncontrolled MARC 21 Fields", "pgdbdata"); + + // Controlled Fields for book +// $db->exec ("select marcfields.text, marctags.name, mn_books_marcauthrecs.* " . +// "from mn_books_marcauthrecs, marcfields, marctags " . +// "where mn_books_marcauthrecs.fk_books = $fk_books " . +// "and marcfields.fk_marcauthrecs = mn_books_marcauthrecs.fk_marcauthrecs " . +// "and marctags.pk = mn_books_marcauthrecs.fk_marctags " . +// "and marcfields.fk_marctags like 'A1%' order by marctags.name, marcfields.text;"); + +// $table = new ListMarcFieldsTable (); +// $table->PrintTable ($db, "Controlled MARC 21 Fields", "pgdbdata"); + +// $f2 = new SQLForm ("mn_books_marcauthrecs", "get"); +// $f2->KeySelect ("fk_marctags", "fk_marctags", "Tag to Link", SQLCHAR, 40, 40, true); +// $f2->last->LoadSQL ("select pk as key, name as caption from marctags where pk like 'B%' and type IS NOT NULL and not exists (select * from mn_books_marcauthrecs as mnm, marctags as mt where mnm.fk_books = $fk_books and mnm.fk_marctags = mt.pk and mt.excludes = marctags.excludes) order by name"); +// $f2->last->DefValue ("B100"); +// $f2->last->ToolTip ("Select a Bibliographic MARC Tag."); +// $f2->Hidden ("fk_books"); +// $f2->Hidden ("mode", "add"); +// $f2->Hidden ("step", "first"); +// $f2->Output ("Link Controlled Field", "Link Controlled Field"); + + // Categories for book + $db->exec ("select * from categories, mn_books_categories " . + "where categories.pk = mn_books_categories.fk_categories " . + "and mn_books_categories.fk_books =$fk_books " . + "order by category;"); + $table = new ListCategoriesTable (); + $table->PrintTable ($db, "Categories", "pgdbdata"); + + // Subjects for book + $db->exec ("select * from subjects, mn_books_subjects " . + "where subjects.pk = mn_books_subjects.fk_subjects " . + "and mn_books_subjects.fk_books =$fk_books " . + "order by subject;"); + $table = new ListSubjectsTable (); + $table->PrintTable ($db, "Subjects", "pgdbdata"); + + form_open ("mn_books_subjects"); + form_hidden ("mode", "add"); + form_hidden ("step", "update"); + form_hidden ("fk_books", $fk_books); + echo ("Quick link subject: Use internal subject #!\n"); + form_submit ("Link Subject"); + echo ("(See \"#\" column above.)"); + form_close (); + + // Languages for book + $db->exec ("select langs.pk as pk, lang from langs, mn_books_langs " . + "where mn_books_langs.fk_langs = langs.pk " . + "and fk_books = $fk_books order by lang;"); + $table = new ListLangsTable (); + $table->PrintTable ($db, "Languages", "pgdbdata"); + + form_open ("mn_books_langs"); + form_hidden ("mode", "add"); + form_hidden ("step", "update"); + form_hidden ("fk_books", $fk_books); + echo ("Quick link language: Use 2-letter code!\n"); + form_submit ("Link Language"); + form_close (); + + // LoCCs for book + $db->exec ("select loccs.pk as pk, locc from loccs, mn_books_loccs " . + "where mn_books_loccs.fk_loccs = loccs.pk " . + "and fk_books = $fk_books order by locc;"); + $table = new ListLoccsTable (); + $table->PrintTable ($db, "LoC Classes", "pgdbdata"); + + form_open ("mn_books_loccs"); + form_hidden ("mode", "add"); + form_hidden ("step", "update"); + form_hidden ("fk_books", $fk_books); + echo ("Quick link LoC class: Use code!\n"); + form_submit ("Link LoC Class"); + form_close (); + + // Reviews for book + $db->exec ("select reviews.reviews.*, reviews.reviewers.name from reviews.reviews, reviews.reviewers where fk_books = $fk_books and reviews.reviewers.pk = reviews.reviews.fk_reviewers;"); + $table = new ListReviewsTable (); + $table->PrintTable ($db, "Reviews", "pgdbdata"); + + } +} + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/book.php~ b/catalog/admin/book.php~ new file mode 100644 index 0000000..6f4dde4 --- /dev/null +++ b/catalog/admin/book.php~ @@ -0,0 +1,335 @@ +AddColumn ("$prefix=edit&pk=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&pk=#pk#\">Delete", "", "narrow"); + + $this->AddSimpleColumn ("name", "MARC Tag"); + $this->AddSimpleColumn ("indicators", "MARC Indicators", "narrow"); + $this->AddSimpleColumn ("nonfiling", "Nonfiling Chars", "narrow"); + $this->AddSimpleColumn ("text", "Text"); + } +} + +class ListMarcFieldsTable extends ListTable { + function __construct () { + global $fk_books, $fk_marcauthrecs; + $prefix = "AddColumn ("$prefix=delete&fk_marcauthrecs=#fk_marcauthrecs#&fk_marctags=#fk_marctags#\">Unlink", + "", "narrow"); + // $this->AddColumn ("$prefix=edit&fk_marcauthrecs=#fk_marcauthrecs#&fk_marctags=#fk_marctags#\">Edit Link", "", "narrow"); + + $this->AddSimpleColumn ("name", "MARC Tag"); + // $this->AddSimpleColumn ("indicators", "MARC Indicators", "narrow"); + // $this->AddSimpleColumn ("nonfiling", "Nonfiling Chars", "narrow"); + $this->AddSimpleColumn ("text", "Text"); + } +} + +class ListAuthorsTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_authors=#pk#&fk_roles=#fk_roles#\">Unlink", + "Link", + "narrow"); + $this->AddColumn ("$prefix=edit&fk_authors=#pk#&fk_roles=#fk_roles#\">Edit Link", + "", "narrow"); + $this->AddColumn ("#author#", "Author"); + $this->AddSimpleColumn ("role", "Role", "narrow"); + $this->AddSimpleColumn ("c_heading", "Heading", "narrow"); + $this->AddSimpleColumn ("born_floor", "Born", "narrow right"); + $this->AddSimpleColumn ("died_floor", "Died", "narrow right"); + + $this->AddSubCaption ("All authors for this work."); + } +} + +class ListReviewsTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddSubCaption ("All reviews for this work."); + + $prefix = "AddColumn ("$prefix=edit&fk_reviews=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_reviews=#pk#\">Delete", "", "narrow"); + + $this->AddSimpleColumn ("name", "Reviewer"); + $this->AddSimpleColumn ("review", "Review"); + } +} + +class ListCategoriesTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_categories=#pk#\">Unlink", + "$prefix=add\">Link", "narrow"); + + $this->AddSimpleColumn ("category", "Category"); + + $this->AddSubCaption ("All categories for this work."); + } +} + +class ListSubjectsTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_subjects=#pk#\">Unlink", + "$prefix=add\">Link", "narrow"); + + $this->AddColumn ("#subject#", "Subject"); + //Make the subject name's clickable links to the edit & list of books page + + $this->AddColumn ("#pk#", "#", "narrow"); + //List the Internal Code #. + + $this->AddSubCaption ("All subjects for this work."); + } +} + +class ListLangsTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_langs=#pk#\">Unlink", + "$prefix=add\">Link", "narrow"); + + $this->AddSimpleColumn ("lang", "Language"); + + $this->AddSubCaption ("Languages of all major sections in this work."); + } +} + +class ListLoccsTable extends ListTable { + function __construct () { + global $fk_books; + $prefix = "AddColumn ("$prefix=delete&fk_loccs=#pk#\">Unlink", + "$prefix=add\">Link", "narrow"); + $this->AddSimpleColumn("pk", "Code"); + $this->AddSimpleColumn ("locc", "LoC class"); + + $this->AddSubCaption ("All LoC Classes this work falls into."); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_books"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this book."); + $f->SubCaption ("Press the '$caption' button to continue or hit " . + "the back button on your browser to dismiss."); +} else { + $f->Text ("pk", "pk", "EText Nr.", SQLINT, 20, 5, true); + $f->ToolTip ("Enter the ebook number."); + $f->Text ("release_date", "release_date", "Release Date", SQLCHAR, 20, 20, false); + $f->ToolTip ("Enter the official release date."); + $f->CheckBox ("copyrighted", "copyrighted", "Copyrighted", SQLINT); + $f->ToolTip ("Check if book is copyrighted."); + $f->CheckBox ("updatemode", "updatemode", "Manual Update", SQLINT); + $f->ToolTip ("Check if book is manually updated."); + + $f->LoadData ("select * from books where pk = $fk_books"); +} +$f->Hidden ("fk_books"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into books " . $sql)) { + msg ("Book added !"); + } else { + error_msg ("Could not add Book!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + // set manually updated mode + if ($db->Exec ("update books set " . $sql . "where pk = $fk_books")) { + msg ("Book modified !"); + } else { + error_msg ("Could not modify book !"); + } + } +} +if (isupdatemode ("delete")) { + $db->exec ("delete from files where fk_books = $fk_books"); + $db->exec ("delete from attributes where fk_books = $fk_books"); + $db->exec ("delete from reviews.reviews where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_authors where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_langs where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_loccs where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_subjects where fk_books = $fk_books"); + $db->Exec ("delete from mn_books_categories where fk_books = $fk_books"); + if ($db->Exec ("delete from books where pk = $fk_books")) { + msg ("Book deleted !"); + } else { + error_msg ("Could not delete book !"); + } +} + +if (isupdate ()) { + getint ("fk_books"); + echo ("

Back to Book

\n\n"); +} else { + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + + p ("Goto Edit Files Page — " . + "etext/${fk_books}#bibrec\">Goto Bibrec Page — " . + "etext/${fk_books}#download\">Goto Bibrec Download Page"); + + $db->exec ("select gutindex from books where pk = $fk_books"); + if ($db->FirstRow ()) { + $gutindex = $db->get ("gutindex", SQLCHAR); + if (!empty ($gutindex)) { + echo ("
$gutindex
\n"); + } + } + + // Authors for book + $db->exec ("select authors.pk as pk, author, heading, born_floor, died_floor, " . + "fk_roles, role " . + "from authors, mn_books_authors, roles " . + "where authors.pk = mn_books_authors.fk_authors " . + "and mn_books_authors.fk_roles = roles.pk " . + "and mn_books_authors.fk_books = $fk_books " . + "order by author;"); + $db->calcfields ["c_heading"] = new CalcFieldHeading (); + $table = new ListAuthorsTable (); + $table->PrintTable ($db, "Authors", "pgdbdata"); + + p ("A Summary of Commonly Used MARC 21 Fields"); + + // Uncontrolled Fields for book + $db->exec ("select attributes.*, attriblist.name from attributes, attriblist " . + "where attributes.fk_books = $fk_books and " . + "attributes.fk_attriblist = attriblist.pk " . + "order by attriblist.name;"); + $table = new ListAttributesTable (); + $table->PrintTable ($db, "Uncontrolled MARC 21 Fields", "pgdbdata"); + + // Controlled Fields for book +// $db->exec ("select marcfields.text, marctags.name, mn_books_marcauthrecs.* " . +// "from mn_books_marcauthrecs, marcfields, marctags " . +// "where mn_books_marcauthrecs.fk_books = $fk_books " . +// "and marcfields.fk_marcauthrecs = mn_books_marcauthrecs.fk_marcauthrecs " . +// "and marctags.pk = mn_books_marcauthrecs.fk_marctags " . +// "and marcfields.fk_marctags like 'A1%' order by marctags.name, marcfields.text;"); + +// $table = new ListMarcFieldsTable (); +// $table->PrintTable ($db, "Controlled MARC 21 Fields", "pgdbdata"); + +// $f2 = new SQLForm ("mn_books_marcauthrecs", "get"); +// $f2->KeySelect ("fk_marctags", "fk_marctags", "Tag to Link", SQLCHAR, 40, 40, true); +// $f2->last->LoadSQL ("select pk as key, name as caption from marctags where pk like 'B%' and type IS NOT NULL and not exists (select * from mn_books_marcauthrecs as mnm, marctags as mt where mnm.fk_books = $fk_books and mnm.fk_marctags = mt.pk and mt.excludes = marctags.excludes) order by name"); +// $f2->last->DefValue ("B100"); +// $f2->last->ToolTip ("Select a Bibliographic MARC Tag."); +// $f2->Hidden ("fk_books"); +// $f2->Hidden ("mode", "add"); +// $f2->Hidden ("step", "first"); +// $f2->Output ("Link Controlled Field", "Link Controlled Field"); + + // Categories for book + $db->exec ("select * from categories, mn_books_categories " . + "where categories.pk = mn_books_categories.fk_categories " . + "and mn_books_categories.fk_books =$fk_books " . + "order by category;"); + $table = new ListCategoriesTable (); + $table->PrintTable ($db, "Categories", "pgdbdata"); + + // Subjects for book + $db->exec ("select * from subjects, mn_books_subjects " . + "where subjects.pk = mn_books_subjects.fk_subjects " . + "and mn_books_subjects.fk_books =$fk_books " . + "order by subject;"); + $table = new ListSubjectsTable (); + $table->PrintTable ($db, "Subjects", "pgdbdata"); + + form_open ("mn_books_subjects"); + form_hidden ("mode", "add"); + form_hidden ("step", "update"); + form_hidden ("fk_books", $fk_books); + echo ("Quick link subject: Use internal subject #!\n"); + form_submit ("Link Subject"); + echo ("(See \"#\" column above.)"); + form_close (); + + // Languages for book + $db->exec ("select langs.pk as pk, lang from langs, mn_books_langs " . + "where mn_books_langs.fk_langs = langs.pk " . + "and fk_books = $fk_books order by lang;"); + $table = new ListLangsTable (); + $table->PrintTable ($db, "Languages", "pgdbdata"); + + form_open ("mn_books_langs"); + form_hidden ("mode", "add"); + form_hidden ("step", "update"); + form_hidden ("fk_books", $fk_books); + echo ("Quick link language: Use 2-letter code!\n"); + form_submit ("Link Language"); + form_close (); + + // LoCCs for book + $db->exec ("select loccs.pk as pk, locc from loccs, mn_books_loccs " . + "where mn_books_loccs.fk_loccs = loccs.pk " . + "and fk_books = $fk_books order by locc;"); + $table = new ListLoccsTable (); + $table->PrintTable ($db, "LoC Classes", "pgdbdata"); + + form_open ("mn_books_loccs"); + form_hidden ("mode", "add"); + form_hidden ("step", "update"); + form_hidden ("fk_books", $fk_books); + echo ("Quick link LoC class: Use code!\n"); + form_submit ("Link LoC Class"); + form_close (); + + // Reviews for book + $db->exec ("select reviews.reviews.*, reviews.reviewers.name from reviews.reviews, reviews.reviewers where fk_books = $fk_books and reviews.reviewers.pk = reviews.reviews.fk_reviewers;"); + $table = new ListReviewsTable (); + $table->PrintTable ($db, "Reviews", "pgdbdata"); + + } +} + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/books_form.php b/catalog/admin/books_form.php new file mode 100644 index 0000000..992ef8a --- /dev/null +++ b/catalog/admin/books_form.php @@ -0,0 +1,47 @@ +Search a book\n"); + +form_open ("books_list"); +?> + + + + + + + + + + + + + + + + + + + +
+
+ +Add a book\n"); + +pagefooter (); +?> diff --git a/catalog/admin/books_form.php~ b/catalog/admin/books_form.php~ new file mode 100644 index 0000000..b371e45 --- /dev/null +++ b/catalog/admin/books_form.php~ @@ -0,0 +1,45 @@ +Search a book\n"); + +form_open ("books_list"); +?> + + + + + + + + + + + + + + + + + + + +
+
+ +Add a book\n"); + +pagefooter (); +?> diff --git a/catalog/admin/books_list.php b/catalog/admin/books_list.php new file mode 100644 index 0000000..f924182 --- /dev/null +++ b/catalog/admin/books_list.php @@ -0,0 +1,56 @@ +AddColumn ("Edit", + "Add", "left", "1%"); + $this->AddColumn ("Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("fk_books", "Nr.", "right", "1%"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddSimpleColumn ("title", "Title"); + } +} + +$db = $config->db (); +$f = $db->GetFormatter (); + +if (isset ($author)) { + $author = $f->f ("$author%", SQLCHAR); + $author = "and author ilike $author "; +} +if (isset ($title)) { + $title = $f->f ("%$title%", SQLCHAR); + $title = "and title ilike $title "; +} +if (isset ($nr)) { + $nr = $f->f ($nr, SQLINT); + $nr = "and fk_books = $nr "; +} + +$where = substr ($author . $title . $nr, 4); + +if (strlen ($where)) { + $where = "where $where"; + + $db->exec ("select * from v_books $where order by author, title"); + + $table = new ListBooksTable (); + $table->PrintTable ($db, $caption); +} else { + msg ("Please enter at least one search argument."); +} + +pagefooter (); +?> diff --git a/catalog/admin/books_list.php~ b/catalog/admin/books_list.php~ new file mode 100644 index 0000000..cace8dc --- /dev/null +++ b/catalog/admin/books_list.php~ @@ -0,0 +1,55 @@ +AddColumn ("Edit", + "Add", "left", "1%"); + $this->AddColumn ("Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("fk_books", "Nr.", "right", "1%"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddSimpleColumn ("title", "Title"); + } +} + +$db = $config->db (); +$f = $db->GetFormatter (); + +if (isset ($author)) { + $author = $f->f ("$author%", SQLCHAR); + $author = "and author ilike $author "; +} +if (isset ($title)) { + $title = $f->f ("%$title%", SQLCHAR); + $title = "and title ilike $title "; +} +if (isset ($nr)) { + $nr = $f->f ($nr, SQLINT); + $nr = "and fk_books = $nr "; +} + +$where = substr ($author . $title . $nr, 4); + +if (strlen ($where)) { + $where = "where $where"; + + $db->exec ("select * from v_books $where order by author, title"); + + $table = new ListBooksTable (); + $table->PrintTable ($db, $caption); +} else { + msg ("Please enter at least one search argument."); +} + +pagefooter (); +?> diff --git a/catalog/admin/cat.php b/catalog/admin/cat.php new file mode 100644 index 0000000..b230e29 --- /dev/null +++ b/catalog/admin/cat.php @@ -0,0 +1,17 @@ + diff --git a/catalog/admin/cat.php~ b/catalog/admin/cat.php~ new file mode 100644 index 0000000..8e5c6fc --- /dev/null +++ b/catalog/admin/cat.php~ @@ -0,0 +1,16 @@ + diff --git a/catalog/admin/catalog-o-matic.php b/catalog/admin/catalog-o-matic.php new file mode 100644 index 0000000..d6641f5 --- /dev/null +++ b/catalog/admin/catalog-o-matic.php @@ -0,0 +1,642 @@ +db (); + +echo ("after db () ...\n"); flush (); + +$db->logger = new logger (); + +echo ("Initializing ...\n"); flush (); + +$db->Exec ("select pk, lang from langs"); +if ($db->FirstRow ()) { + do { + $languages[$db->Get ("lang", SQLCHAR)] = $db->Get ("pk", SQLCHAR); + } while ($db->NextRow ()); +} + +$db->exec ("select pk, filetype from filetypes"); +if ($db->FirstRow ()) { + do { + $filetypes[$db->Get ("pk", SQLCHAR)] = $db->Get ("filetype", SQLCHAR); + } while ($db->NextRow ()); +} + +$db->exec ("select pk, compression from compressions"); +if ($db->FirstRow ()) { + do { + $compressions[$db->Get ("pk", SQLCHAR)] = $db->Get ("compression", SQLCHAR); + } while ($db->NextRow ()); +} + +$db->exec ("select pk from encodings"); +if ($db->FirstRow ()) { + do { + $encodings[$db->Get ("pk", SQLCHAR)] = 1; + } while ($db->NextRow ()); +} + +$db->exec ("select pk, role from roles"); +if ($db->FirstRow ()) { + do { + $roles[$db->Get ("role", SQLCHAR)] = $db->get ("pk", SQLCHAR); + } while ($db->NextRow ()); +} + +$importfilename = $argv[1]; +if (empty ($importfilename)) + $importfilename = $config->catalogupdatelog; + +echo ("Processing $importfilename ...\n"); flush (); + +$old_etext_number = -1; + +function guess_filetype ($filename) { + // guesses filetype, encoding from filename only + // + // needs following hashes: + // usually loaded from the same tables in the database + // $filetypes: 'txt' => 'Plain text' + // $encodings: 'us-ascii' + global $filetypes, $encodings; + + $extension_aliases = array ( + 'htm' => 'html', + 'tif' => 'tiff', + 'jpeg' => 'jpg', + 'midi' => 'mid' + ); + + $ft = $enc = null; + $base = $ext = ""; + $base_after_hyphen = ""; + + if (preg_match ("/^(.*)\.(.*)$/", $filename, $matches)) { + $base = strtolower ($matches[1]); + $ext = strtolower ($matches[2]); + } + + $post10k = preg_match ("/^\d{5}(-|$)/", $base); + if (preg_match ("/-(.*)$/", $base, $matches)) + $base_after_hyphen = $matches[1]; + + // guess filetype from file extension + if (isset ($extension_aliases[$ext])) { + $ext = $extension_aliases[$ext]; + } + if (isset ($filetypes[$ext])) { + $ft = $ext; + } + + if (preg_match ("/[-_]index\.html?$/i", $filename)) { + $ft = "index"; + } + if (preg_match ("/readme\.txt$/i", $filename)) { + $ft = "readme"; + } + if (preg_match ("/license\.txt$/i", $filename)) { + $ft = "license"; + } + if (preg_match ("/page-images/i", $filename)) { + $ft = "pageimages"; + } + + // guess encoding from file name + if ($ext == "txt") { + if ($post10k) { + switch ($base_after_hyphen) { + case "" : $enc = "us-ascii"; break; + case "8" : $enc = "iso-8859-1"; break; + case "0" : $enc = "utf-8"; break; + case "5" : $enc = "big5"; break; + } + } else { + $enc = "us-ascii"; + if (preg_match ("/^8\w.+\d\da?$/", $base)) + $enc = "iso-8859-1"; + if (preg_match ("/^8\w.+\d\du$/", $base)) + $enc = "utf-8"; + } + } + + return array ($ft, $enc); +} + +function fix_encoding ($encoding) { + global $encodings; + + $encoding_aliases = array ( + 'ascii' => 'us-ascii', + 'usascii' => 'us-ascii', + 'iso88591' => 'iso-8859-1', + 'latin1' => 'iso-8859-1', + 'iso88592' => 'iso-8859-2', + 'latin2' => 'iso-8859-2', + 'iso88593' => 'iso-8859-3', + 'latin3' => 'iso-8859-3', + 'iso88594' => 'iso-8859-4', + 'latin4' => 'iso-8859-4', + 'iso88595' => 'iso-8859-5', + 'cyrillic' => 'iso-8859-5', + 'iso88596' => 'iso-8859-6', + 'arabic' => 'iso-8859-6', + 'iso88597' => 'iso-8859-7', + 'greek' => 'iso-8859-7', + 'iso88598' => 'iso-8859-8', + 'hebrew' => 'iso-8859-8', + 'iso88599' => 'iso-8859-9', + 'latin5' => 'iso-8859-9', + 'iso885910' => 'iso-8859-10', + 'latin6' => 'iso-8859-10', + 'iso885913' => 'iso-8859-13', + 'iso885914' => 'iso-8859-14', + 'latin8' => 'iso-8859-14', + 'iso885915' => 'iso-8859-15', + 'latin9' => 'iso-8859-15', + 'iso885916' => 'iso-8859-16', + 'latin10' => 'iso-8859-16', + 'utf7' => 'utf-7', + 'utf8' => 'utf-8', + 'win1250' => 'windows-1250', + 'win1251' => 'windows-1251', + 'win1252' => 'windows-1252', + 'win1253' => 'windows-1253', + 'koi8r' => 'koi8-r' + ); + + $pat[] = "/[- _=<]/"; $rep[] = ""; + $pat[] = "/^unicode/"; $rep[] = ""; + $pat[] = "/^windowscodepage/"; $rep[] = "win"; + $pat[] = "/^windows/"; $rep[] = "win"; + $pat[] = "/^codepage/"; $rep[] = "win"; + $pat[] = "/^cp/"; $rep[] = "win"; + $pat[] = "/^isolatin/"; $rep[] = "latin"; + + $encoding = strtolower ($encoding); + $encoding = preg_replace ($pat, $rep, $encoding); + + if (isset ($encodings[$encoding])) { + return $encoding; + } + if (isset ($encoding_aliases[$encoding])) { + return $encoding_aliases[$encoding]; + } + + if (strpos ($encoding, "iso88591")) { + $encoding = "iso-8859-1"; + } elseif (strpos ($encoding, "utf8")) { + $encoding = "utf-8"; + } else { + $encoding = null; + // print ("#$nr: unknown encoding $enc\n"); + } + return $encoding; +} + +function encode_language ($l) { + global $languages; + $l = ucfirst ($l); + + if (isset ($languages[$l])) { + return $languages[$l]; + } + return null; +} + +function decode_author ($whole) { + global $roles; + + $parts = preg_split ("/ *, */", $whole); + $names = array (); + $name = ""; + $born = null; + $died = null; + $role = "aut"; + + foreach ($parts as $part) { + if (empty ($part)) + continue; + if (preg_match ("/^(\d+\??)-(\d*\??)$/", $part, $matches)) { + $born = "$matches[1]"; + $died = "$matches[2]"; + continue; + } + if (preg_match ("/^-(\d+)$/", $part, $matches)) { + $died = "$matches[1]"; + continue; + } + if (isset ($roles[$part])) { + $role = $roles[$part]; + continue; + } + array_push ($names, $part); + } + + return array (join (", ", $names), $born, $died, $role); +} + +function insert_author ($author, $born, $died) { + global $db; + if (empty ($author)) + return null; + + $sql_author = $db->f ($author, SQLCHAR); + $sql_born = $db->f ($born, SQLINT); + $sql_died = $db->f ($died, SQLINT); + $sql_author_like = $db->f ("$author%", SQLCHAR); + + $pk = 0; + $db->exec ("select pk from authors where author ilike $sql_author_like order by pk"); + if ($db->FirstRow ()) { + $pk = $db->Get ("pk", SQLINT); + } else { + // try aliases + $db->exec ("select fk_authors from aliases where alias ilike $sql_author_like order by fk_authors"); + if ($db->FirstRow ()) { + $pk = $db->Get ("fk_authors", SQLINT); + } + } + if ($pk == 0) { + $db->exec ("insert into authors (author, born_floor, died_floor, born_ceil, died_ceil) " . + "values ($sql_author, $sql_born, $sql_died, $sql_born, $sql_died)"); + $db->exec ("select pk from authors where author = $sql_author"); + $pk = $db->Get ("pk", SQLINT); + echo ("Added author '$author' to database. !!!!\n"); + } + return $pk; +} + +function insert_title ($etext_number, $title, $marc = 245) { + global $db, $titles; + if (empty ($title)) + return; + + $nonfilings = array ('The ', 'A ', 'An ', + 'Der ', 'Die ', 'Das ', 'Eine ', 'Ein ', + 'La ', 'Le ', 'Les ', 'L\'', + 'El '); + $nonfiling = 0; + + foreach ($nonfilings as $key => $value) { + if (preg_match ("/^$value/", $title)) { + $nonfiling = strlen ($value); + } + } + + $title = preg_replace ("/--/", "\xE2\x80\x94", $title); + $title = preg_replace ("/ *_ */", "\n", $title); + $sql_title = $db->f ($title, SQLCHAR); + $sql_etext_number = $db->f ($etext_number, SQLINT); + $sql_marc = $db->f ($marc, SQLINT); + $sql_nonfiling = $db->f ($nonfiling, SQLINT); + + $db->exec ("select pk from attributes where fk_books = $sql_etext_number and text = $sql_title"); + if (!$db->FirstRow ()) { + $db->exec ("insert into attributes (fk_books, text, nonfiling, fk_attriblist) " . + "values ($sql_etext_number, $sql_title, $sql_nonfiling, $sql_marc)"); + + echo ("Added title '$title' to book $etext_number\n"); + } +} + +function capture ($tok, $e) { + $matches = array (); + if (preg_match ("/^$tok: (.*)$/im", $e, $matches)) + return $matches[1]; + return null; +} + +function process_section ($e) { + global $db, $filetypes, $compressions, $encodings, $roles, $old_etext_number; + $etext_number = $pk_author = null; + $cnt_authors = $updatemode = 0; + $got_title = 0; + + // try to read etext_number from inputfile + $etext_number = capture ("Etext-Nr", $e); + if (empty ($etext_number)) { + // no etext_number ? + // try to compute etext_number from directory + $directory = capture ("directory", $e); + if (preg_match ("/^(?:\d\/)+(\d{2,5})/", $directory, $matches)) { + $etext_number = intval ($matches[1]); + // double-check this + $dir = etext2dir ($etext_number); + if (strncmp ("$directory/", $dir, strlen ($dir))) + $etext_number = null; + } elseif (preg_match ("/^([1-9])$/", $directory, $matches)) { + $etext_number = intval ($matches[1]); + } + } + + if ($etext_number != $old_etext_number) { + echo ("----------\n\n"); + $old_etext_number = $etext_number; + } + + // insert file into files table + if ($filename = capture ("filename", $e)) { + $matches = array (); + + $directory = capture ("directory", $e); + $mtime = capture ("mtime", $e); + $size = capture ("size", $e); + $edition = capture ("edition", $e); + $filetype = capture ("filetype", $e); + $obsoleted = capture ("obsoleted", $e); + $encoding = fix_encoding (capture ("encoding", $e)); + $zipmember = capture ("Zipmemberfilename", $e); + + /* + $md5hash = @pack ("H*", capture ("md5.hex", $e)); + $sha1hash = @pack ("H*", capture ("sha1.hex", $e)); + $kzhash = @pack ("H*", capture ("kzhash.hex", $e)); + $ed2khash = @pack ("H*", capture ("ed2khash.hex", $e)); + $tigertreehash = @pack ("H*", capture ("tigertree.hex", $e)); + */ + + $md5hash = capture ("md5.hex", $e); + $sha1hash = capture ("sha1.hex", $e); + $kzhash = capture ("kzhash.hex", $e); + $ed2khash = capture ("ed2khash.hex", $e); + $tigertreehash = capture ("tigertree.hex", $e); + + // filetype and encoding + list ($fk_filetypes, $fk_encodings) = + guess_filetype (empty ($zipmember) ? $filename : $zipmember); + + // the encoding is better taken from the file, if present + if (isset ($encodings[$encoding])) { + $fk_encodings = $encoding; + } + + // the filetype is better taken from the file, if present (not used for now) + // if (!empty ($filetype) && isset ($filetypes[$filetype])) { + // $fk_filetypes = $filetype; + // } + + // compression + $fk_compressions = 'none'; + if (preg_match ("/^(.*)\.(.*)$/", $filename, $matches)) { + if (isset ($compressions[strtolower ($matches[2])])) { + $fk_compressions = strtolower ($matches[2]); + } + } + + // obsoleted + if (preg_match ("/\/old(\/|$)/", $directory)) { + $obsoleted = 1; + } + + $diskstatus = 0; + + // hide image files + if (strpos ($directory, "/$etext_number-")) { + if (in_array ($fk_filetypes, array ("jpg", "png", "gif", "svg", "css", "xsl"))) + $diskstatus = 1; + if (preg_match ("/\/images(\/|$)/", $directory)) + $diskstatus = 1; + if (preg_match ("/-h\/files(\/|$)/", $directory)) + $diskstatus = 1; + } + + $sql_diskstatus = $db->f ($diskstatus, SQLINT); + $sql_fk_filetypes = $db->f ($fk_filetypes, SQLCHAR); + $sql_fk_compressions = $db->f ($fk_compressions, SQLCHAR); + $sql_fk_encodings = $db->f ($fk_encodings, SQLCHAR); + $sql_mtime = $db->f ($mtime, SQLDATE); + $sql_size = $db->f ($size, SQLINT); + $sql_edition = $db->f ($edition, SQLINT); + $sql_obsoleted = $db->f ($obsoleted, SQLINT); + $sql_etext_number = $db->f ($etext_number, SQLINT); + $sql_filename = $db->f ("$directory/$filename", SQLCHAR); + $sql_md5hash = $db->f ($md5hash, SQLBYTE); + $sql_sha1hash = $db->f ($sha1hash, SQLBYTE); + $sql_kzhash = $db->f ($kzhash, SQLBYTE); + $sql_ed2khash = $db->f ($ed2khash, SQLBYTE); + $sql_tigertreehash = $db->f ($tigertreehash, SQLBYTE); + + $fields = + (empty ($etext_number) ? "" : "fk_books = $sql_etext_number, ") . + (empty ($fk_filetypes) ? "" : "fk_filetypes = $sql_fk_filetypes, ") . + (empty ($fk_encodings) ? "" : "fk_encodings = $sql_fk_encodings, ") . + (empty ($fk_compressions) ? "" : "fk_compressions = $sql_fk_compressions, ") . + (empty ($md5hash) ? "" : "md5hash = $sql_md5hash, ") . + (empty ($sha1hash) ? "" : "sha1hash = $sql_sha1hash, ") . + (empty ($kzhash) ? "" : "kzhash = $sql_kzhash, ") . + (empty ($ed2khash) ? "" : "ed2khash = $sql_ed2khash, ") . + (empty ($tigertreehash) ? "" : "tigertreehash = $sql_tigertreehash, ") . + (empty ($edition) ? "" : "edition = $sql_edition, ") . + (empty ($obsoleted) ? "" : "obsoleted = $sql_obsoleted, ") . + (empty ($size) ? "" : "filesize = $sql_size, ") . + (empty ($mtime) ? "" : "filemtime = $sql_mtime, ") . + "diskstatus = $sql_diskstatus"; + + // $fields = rtrim ($fields, ", "); + + $db->BeginTrans (); + + $db->exec ("select pk from files where filename = $sql_filename"); + $newfile = !$db->FirstRow (); + + if ($newfile) { + $db->exec ("insert into files (filename, diskstatus) values ($sql_filename, 0);"); + } + + $db->exec ("update files set $fields where filename = $sql_filename"); + + $db->Commit (); + + echo (($newfile ? "Added" : "Updated") . " file $directory/$filename " . + "($sql_etext_number $sql_fk_filetypes $sql_fk_compressions $sql_fk_encodings $sql_diskstatus $sql_obsoleted)\n"); + } + + // maybe insert book into books table + if (!empty ($etext_number)) { + $db->BeginTrans (); + + $sql_etext_number = $db->f ($etext_number, SQLINT); + $db->exec ("select * from books where pk = $sql_etext_number"); + + if ($db->FirstRow ()) { + $updatemode = $db->get ("updatemode", SQLINT); // 0 = auto, 1 = manual + } else { + $db->exec ("insert into books (pk) values ($sql_etext_number)"); + echo ("Inserted book $etext_number into database\n"); + } + + if ($updatemode == 0) { + if ($fk_encodings != "utf-8") { + iconv_set_encoding ("internal_encoding", "UTF-8"); + $converted = iconv (strtoupper ($fk_encodings), "UTF-8", $e); + if ($converted !== FALSE) { + $e = $converted; + } + } + $lines = preg_split ("/\n/", $e); + foreach ($lines as $line) { + if (empty ($line)) continue; + if (!preg_match ("/^(.*?):\s+(.*)$/", $line, $matches)) + continue; + list ($dummy, $key, $value) = $matches; // preg_split ("/:\s+/", $line); //FIXME + if (empty ($value)) continue; + + if (isset ($roles[$key])) { + list ($author, $born, $died, $role) = decode_author ($value); + $pk_author = insert_author ($author, $born, $died); + if ($key != "Author") { + $role = $roles[$key]; + } + if ($pk_author) { + $sql_fk_authors = $db->f ($pk_author, SQLINT); + $sql_fk_roles = $db->f ($role, SQLCHAR); + $db->exec ("select * from mn_books_authors " . + "where fk_books = $sql_etext_number and fk_authors = $sql_fk_authors " . + "and fk_roles = $sql_fk_roles"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_authors (fk_books, fk_authors, fk_roles) " . + "values ($sql_etext_number, $sql_fk_authors, $sql_fk_roles)"); + echo ("Added author '$author' role $role to book $etext_number\n"); + } + } + $cnt_authors++; + continue; + } + if ($key == "Title") { + insert_title ($etext_number, $value, 245); + $got_title = 1; + continue; + } + if ($key == "Alternate Title") { + insert_title ($etext_number, $value, 246); + continue; + } + if ($key == "Contents") { + insert_title ($etext_number, $value, 505); + continue; + } + if ($key == "Language") { + $lang = encode_language ($value); + if (!empty ($lang)) { + $sql_lang = $db->f ($lang, SQLCHAR); + $db->exec ("select * from mn_books_langs " . + "where fk_books = $sql_etext_number and fk_langs = $sql_lang"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_langs (fk_books, fk_langs) " . + "values ($sql_etext_number, $sql_lang)"); + } + } + continue; + } + if ($key == "Locc") { + $sql_locc = $db->f (strtoupper ($value), SQLCHAR); + $db->exec ("select * from mn_books_loccs " . + "where fk_books = $sql_etext_number and fk_loccs = $sql_locc"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_loccs (fk_books, fk_loccs) " . + "values ($sql_etext_number, $sql_locc)"); + } + continue; + } + if ($key == "Subject") { + $sql_subject = $db->f ($value, SQLCHAR); + $db->exec ("select pk from subjects where subject = $sql_subject"); + if (!$db->FirstRow ()) { + $db->exec ("insert into subjects (subject) values ($sql_subject)"); + $db->exec ("select pk from subjects where subject = $sql_subject"); + } + $pk_subjects = $db->Get ("pk", SQLINT); + $sql_fk_subjects = $db->f ($pk_subjects, SQLINT); + + $db->exec ("select * from mn_books_subjects " . + "where fk_books = $sql_etext_number and fk_subjects = $sql_fk_subjects"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_subjects (fk_books, fk_subjects) " . + "values ($sql_etext_number, $sql_fk_subjects)"); + } + continue; + } + if ($key == "Note") { + $sql_note = $db->f ($value, SQLCHAR); + $db->exec ("select * from attributes " . + "where fk_books = $sql_etext_number and text = $sql_note"); + if (!$db->FirstRow ()) { + $db->exec ("insert into attributes (fk_books, fk_attriblist, text) values ($sql_etext_number, 500, $sql_note)"); + } + continue; + } + if ($key == "Copyright") { + $sql_copyrighted = $db->f ($value, SQLINT); + $db->exec ("update books set copyrighted = $sql_copyrighted where pk = $sql_etext_number"); + continue; + } + if ($key == "Category") { + $sql_category = $db->f ($value, SQLCHAR); + $db->exec ("select pk from categories where category = $sql_category"); + if ($db->FirstRow ()) { + $fk_categories = $db->get ("pk", SQLINT); + $sql_fk_categories = $db->f ($fk_categories, SQLINT); + + $db->exec ("select * from mn_books_categories " . + "where fk_books = $sql_etext_number and fk_categories = $sql_fk_categories"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_categories (fk_books, fk_categories) " . + "values ($sql_etext_number, $fk_categories)"); + } + } + continue; + } + if ($key == "Release-Date") { + if (strpos ($value, ',') === false) { + $vale = "1 $value"; + } + $release_date = strtotime ("$value"); + $sql_release_date = $db->f ($release_date, SQLDATE); + $db->exec ("update books set release_date = $sql_release_date where pk = $sql_etext_number"); + continue; + } + } + + // hack! makefiles.pl sorts filenames so that 8-bit ones come first + // this way we prefer titles etc. from 8-bit files over html and 7-bit files + if ($got_title) { + $db->exec ("update books set updatemode = 1 where pk = $sql_etext_number"); + } + + $db->Commit (); + } + } +} + +register_shutdown_function ('rollback_transaction'); +set_time_limit (0); + +$buffer = ""; +if ($hd = fopen ($importfilename, "r")) { + while (!feof ($hd)) { + $line = fgets ($hd); + if (preg_match ("/^---*[\r\n]*$/", $line)) { + process_section ($buffer); + $buffer = ""; + echo ("\n"); flush (); + } else { + $buffer .= $line; + } + } + process_section ($buffer); + fclose ($hd); +} + +?> diff --git a/catalog/admin/catalog-o-matic.php~ b/catalog/admin/catalog-o-matic.php~ new file mode 100644 index 0000000..0e055cc --- /dev/null +++ b/catalog/admin/catalog-o-matic.php~ @@ -0,0 +1,641 @@ +db (); + +echo ("after db () ...\n"); flush (); + +$db->logger = new logger (); + +echo ("Initializing ...\n"); flush (); + +$db->Exec ("select pk, lang from langs"); +if ($db->FirstRow ()) { + do { + $languages[$db->Get ("lang", SQLCHAR)] = $db->Get ("pk", SQLCHAR); + } while ($db->NextRow ()); +} + +$db->exec ("select pk, filetype from filetypes"); +if ($db->FirstRow ()) { + do { + $filetypes[$db->Get ("pk", SQLCHAR)] = $db->Get ("filetype", SQLCHAR); + } while ($db->NextRow ()); +} + +$db->exec ("select pk, compression from compressions"); +if ($db->FirstRow ()) { + do { + $compressions[$db->Get ("pk", SQLCHAR)] = $db->Get ("compression", SQLCHAR); + } while ($db->NextRow ()); +} + +$db->exec ("select pk from encodings"); +if ($db->FirstRow ()) { + do { + $encodings[$db->Get ("pk", SQLCHAR)] = 1; + } while ($db->NextRow ()); +} + +$db->exec ("select pk, role from roles"); +if ($db->FirstRow ()) { + do { + $roles[$db->Get ("role", SQLCHAR)] = $db->get ("pk", SQLCHAR); + } while ($db->NextRow ()); +} + +$importfilename = $argv[1]; +if (empty ($importfilename)) + $importfilename = $config->catalogupdatelog; + +echo ("Processing $importfilename ...\n"); flush (); + +$old_etext_number = -1; + +function guess_filetype ($filename) { + // guesses filetype, encoding from filename only + // + // needs following hashes: + // usually loaded from the same tables in the database + // $filetypes: 'txt' => 'Plain text' + // $encodings: 'us-ascii' + global $filetypes, $encodings; + + $extension_aliases = array ( + 'htm' => 'html', + 'tif' => 'tiff', + 'jpeg' => 'jpg', + 'midi' => 'mid' + ); + + $ft = $enc = null; + $base = $ext = ""; + $base_after_hyphen = ""; + + if (preg_match ("/^(.*)\.(.*)$/", $filename, $matches)) { + $base = strtolower ($matches[1]); + $ext = strtolower ($matches[2]); + } + + $post10k = preg_match ("/^\d{5}(-|$)/", $base); + if (preg_match ("/-(.*)$/", $base, $matches)) + $base_after_hyphen = $matches[1]; + + // guess filetype from file extension + if (isset ($extension_aliases[$ext])) { + $ext = $extension_aliases[$ext]; + } + if (isset ($filetypes[$ext])) { + $ft = $ext; + } + + if (preg_match ("/[-_]index\.html?$/i", $filename)) { + $ft = "index"; + } + if (preg_match ("/readme\.txt$/i", $filename)) { + $ft = "readme"; + } + if (preg_match ("/license\.txt$/i", $filename)) { + $ft = "license"; + } + if (preg_match ("/page-images/i", $filename)) { + $ft = "pageimages"; + } + + // guess encoding from file name + if ($ext == "txt") { + if ($post10k) { + switch ($base_after_hyphen) { + case "" : $enc = "us-ascii"; break; + case "8" : $enc = "iso-8859-1"; break; + case "0" : $enc = "utf-8"; break; + case "5" : $enc = "big5"; break; + } + } else { + $enc = "us-ascii"; + if (preg_match ("/^8\w.+\d\da?$/", $base)) + $enc = "iso-8859-1"; + if (preg_match ("/^8\w.+\d\du$/", $base)) + $enc = "utf-8"; + } + } + + return array ($ft, $enc); +} + +function fix_encoding ($encoding) { + global $encodings; + + $encoding_aliases = array ( + 'ascii' => 'us-ascii', + 'usascii' => 'us-ascii', + 'iso88591' => 'iso-8859-1', + 'latin1' => 'iso-8859-1', + 'iso88592' => 'iso-8859-2', + 'latin2' => 'iso-8859-2', + 'iso88593' => 'iso-8859-3', + 'latin3' => 'iso-8859-3', + 'iso88594' => 'iso-8859-4', + 'latin4' => 'iso-8859-4', + 'iso88595' => 'iso-8859-5', + 'cyrillic' => 'iso-8859-5', + 'iso88596' => 'iso-8859-6', + 'arabic' => 'iso-8859-6', + 'iso88597' => 'iso-8859-7', + 'greek' => 'iso-8859-7', + 'iso88598' => 'iso-8859-8', + 'hebrew' => 'iso-8859-8', + 'iso88599' => 'iso-8859-9', + 'latin5' => 'iso-8859-9', + 'iso885910' => 'iso-8859-10', + 'latin6' => 'iso-8859-10', + 'iso885913' => 'iso-8859-13', + 'iso885914' => 'iso-8859-14', + 'latin8' => 'iso-8859-14', + 'iso885915' => 'iso-8859-15', + 'latin9' => 'iso-8859-15', + 'iso885916' => 'iso-8859-16', + 'latin10' => 'iso-8859-16', + 'utf7' => 'utf-7', + 'utf8' => 'utf-8', + 'win1250' => 'windows-1250', + 'win1251' => 'windows-1251', + 'win1252' => 'windows-1252', + 'win1253' => 'windows-1253', + 'koi8r' => 'koi8-r' + ); + + $pat[] = "/[- _=<]/"; $rep[] = ""; + $pat[] = "/^unicode/"; $rep[] = ""; + $pat[] = "/^windowscodepage/"; $rep[] = "win"; + $pat[] = "/^windows/"; $rep[] = "win"; + $pat[] = "/^codepage/"; $rep[] = "win"; + $pat[] = "/^cp/"; $rep[] = "win"; + $pat[] = "/^isolatin/"; $rep[] = "latin"; + + $encoding = strtolower ($encoding); + $encoding = preg_replace ($pat, $rep, $encoding); + + if (isset ($encodings[$encoding])) { + return $encoding; + } + if (isset ($encoding_aliases[$encoding])) { + return $encoding_aliases[$encoding]; + } + + if (strpos ($encoding, "iso88591")) { + $encoding = "iso-8859-1"; + } elseif (strpos ($encoding, "utf8")) { + $encoding = "utf-8"; + } else { + $encoding = null; + // print ("#$nr: unknown encoding $enc\n"); + } + return $encoding; +} + +function encode_language ($l) { + global $languages; + $l = ucfirst ($l); + + if (isset ($languages[$l])) { + return $languages[$l]; + } + return null; +} + +function decode_author ($whole) { + global $roles; + + $parts = preg_split ("/ *, */", $whole); + $names = array (); + $name = ""; + $born = null; + $died = null; + $role = "aut"; + + foreach ($parts as $part) { + if (empty ($part)) + continue; + if (preg_match ("/^(\d+\??)-(\d*\??)$/", $part, $matches)) { + $born = "$matches[1]"; + $died = "$matches[2]"; + continue; + } + if (preg_match ("/^-(\d+)$/", $part, $matches)) { + $died = "$matches[1]"; + continue; + } + if (isset ($roles[$part])) { + $role = $roles[$part]; + continue; + } + array_push ($names, $part); + } + + return array (join (", ", $names), $born, $died, $role); +} + +function insert_author ($author, $born, $died) { + global $db; + if (empty ($author)) + return null; + + $sql_author = $db->f ($author, SQLCHAR); + $sql_born = $db->f ($born, SQLINT); + $sql_died = $db->f ($died, SQLINT); + $sql_author_like = $db->f ("$author%", SQLCHAR); + + $pk = 0; + $db->exec ("select pk from authors where author ilike $sql_author_like order by pk"); + if ($db->FirstRow ()) { + $pk = $db->Get ("pk", SQLINT); + } else { + // try aliases + $db->exec ("select fk_authors from aliases where alias ilike $sql_author_like order by fk_authors"); + if ($db->FirstRow ()) { + $pk = $db->Get ("fk_authors", SQLINT); + } + } + if ($pk == 0) { + $db->exec ("insert into authors (author, born_floor, died_floor, born_ceil, died_ceil) " . + "values ($sql_author, $sql_born, $sql_died, $sql_born, $sql_died)"); + $db->exec ("select pk from authors where author = $sql_author"); + $pk = $db->Get ("pk", SQLINT); + echo ("Added author '$author' to database. !!!!\n"); + } + return $pk; +} + +function insert_title ($etext_number, $title, $marc = 245) { + global $db, $titles; + if (empty ($title)) + return; + + $nonfilings = array ('The ', 'A ', 'An ', + 'Der ', 'Die ', 'Das ', 'Eine ', 'Ein ', + 'La ', 'Le ', 'Les ', 'L\'', + 'El '); + $nonfiling = 0; + + foreach ($nonfilings as $key => $value) { + if (preg_match ("/^$value/", $title)) { + $nonfiling = strlen ($value); + } + } + + $title = preg_replace ("/--/", "\xE2\x80\x94", $title); + $title = preg_replace ("/ *_ */", "\n", $title); + $sql_title = $db->f ($title, SQLCHAR); + $sql_etext_number = $db->f ($etext_number, SQLINT); + $sql_marc = $db->f ($marc, SQLINT); + $sql_nonfiling = $db->f ($nonfiling, SQLINT); + + $db->exec ("select pk from attributes where fk_books = $sql_etext_number and text = $sql_title"); + if (!$db->FirstRow ()) { + $db->exec ("insert into attributes (fk_books, text, nonfiling, fk_attriblist) " . + "values ($sql_etext_number, $sql_title, $sql_nonfiling, $sql_marc)"); + + echo ("Added title '$title' to book $etext_number\n"); + } +} + +function capture ($tok, $e) { + $matches = array (); + if (preg_match ("/^$tok: (.*)$/im", $e, $matches)) + return $matches[1]; + return null; +} + +function process_section ($e) { + global $db, $filetypes, $compressions, $encodings, $roles, $old_etext_number; + $etext_number = $pk_author = null; + $cnt_authors = $updatemode = 0; + $got_title = 0; + + // try to read etext_number from inputfile + $etext_number = capture ("Etext-Nr", $e); + if (empty ($etext_number)) { + // no etext_number ? + // try to compute etext_number from directory + $directory = capture ("directory", $e); + if (preg_match ("/^(?:\d\/)+(\d{2,5})/", $directory, $matches)) { + $etext_number = intval ($matches[1]); + // double-check this + $dir = etext2dir ($etext_number); + if (strncmp ("$directory/", $dir, strlen ($dir))) + $etext_number = null; + } elseif (preg_match ("/^([1-9])$/", $directory, $matches)) { + $etext_number = intval ($matches[1]); + } + } + + if ($etext_number != $old_etext_number) { + echo ("----------\n\n"); + $old_etext_number = $etext_number; + } + + // insert file into files table + if ($filename = capture ("filename", $e)) { + $matches = array (); + + $directory = capture ("directory", $e); + $mtime = capture ("mtime", $e); + $size = capture ("size", $e); + $edition = capture ("edition", $e); + $filetype = capture ("filetype", $e); + $obsoleted = capture ("obsoleted", $e); + $encoding = fix_encoding (capture ("encoding", $e)); + $zipmember = capture ("Zipmemberfilename", $e); + + /* + $md5hash = @pack ("H*", capture ("md5.hex", $e)); + $sha1hash = @pack ("H*", capture ("sha1.hex", $e)); + $kzhash = @pack ("H*", capture ("kzhash.hex", $e)); + $ed2khash = @pack ("H*", capture ("ed2khash.hex", $e)); + $tigertreehash = @pack ("H*", capture ("tigertree.hex", $e)); + */ + + $md5hash = capture ("md5.hex", $e); + $sha1hash = capture ("sha1.hex", $e); + $kzhash = capture ("kzhash.hex", $e); + $ed2khash = capture ("ed2khash.hex", $e); + $tigertreehash = capture ("tigertree.hex", $e); + + // filetype and encoding + list ($fk_filetypes, $fk_encodings) = + guess_filetype (empty ($zipmember) ? $filename : $zipmember); + + // the encoding is better taken from the file, if present + if (isset ($encodings[$encoding])) { + $fk_encodings = $encoding; + } + + // the filetype is better taken from the file, if present (not used for now) + // if (!empty ($filetype) && isset ($filetypes[$filetype])) { + // $fk_filetypes = $filetype; + // } + + // compression + $fk_compressions = 'none'; + if (preg_match ("/^(.*)\.(.*)$/", $filename, $matches)) { + if (isset ($compressions[strtolower ($matches[2])])) { + $fk_compressions = strtolower ($matches[2]); + } + } + + // obsoleted + if (preg_match ("/\/old(\/|$)/", $directory)) { + $obsoleted = 1; + } + + $diskstatus = 0; + + // hide image files + if (strpos ($directory, "/$etext_number-")) { + if (in_array ($fk_filetypes, array ("jpg", "png", "gif", "svg", "css", "xsl"))) + $diskstatus = 1; + if (preg_match ("/\/images(\/|$)/", $directory)) + $diskstatus = 1; + if (preg_match ("/-h\/files(\/|$)/", $directory)) + $diskstatus = 1; + } + + $sql_diskstatus = $db->f ($diskstatus, SQLINT); + $sql_fk_filetypes = $db->f ($fk_filetypes, SQLCHAR); + $sql_fk_compressions = $db->f ($fk_compressions, SQLCHAR); + $sql_fk_encodings = $db->f ($fk_encodings, SQLCHAR); + $sql_mtime = $db->f ($mtime, SQLDATE); + $sql_size = $db->f ($size, SQLINT); + $sql_edition = $db->f ($edition, SQLINT); + $sql_obsoleted = $db->f ($obsoleted, SQLINT); + $sql_etext_number = $db->f ($etext_number, SQLINT); + $sql_filename = $db->f ("$directory/$filename", SQLCHAR); + $sql_md5hash = $db->f ($md5hash, SQLBYTE); + $sql_sha1hash = $db->f ($sha1hash, SQLBYTE); + $sql_kzhash = $db->f ($kzhash, SQLBYTE); + $sql_ed2khash = $db->f ($ed2khash, SQLBYTE); + $sql_tigertreehash = $db->f ($tigertreehash, SQLBYTE); + + $fields = + (empty ($etext_number) ? "" : "fk_books = $sql_etext_number, ") . + (empty ($fk_filetypes) ? "" : "fk_filetypes = $sql_fk_filetypes, ") . + (empty ($fk_encodings) ? "" : "fk_encodings = $sql_fk_encodings, ") . + (empty ($fk_compressions) ? "" : "fk_compressions = $sql_fk_compressions, ") . + (empty ($md5hash) ? "" : "md5hash = $sql_md5hash, ") . + (empty ($sha1hash) ? "" : "sha1hash = $sql_sha1hash, ") . + (empty ($kzhash) ? "" : "kzhash = $sql_kzhash, ") . + (empty ($ed2khash) ? "" : "ed2khash = $sql_ed2khash, ") . + (empty ($tigertreehash) ? "" : "tigertreehash = $sql_tigertreehash, ") . + (empty ($edition) ? "" : "edition = $sql_edition, ") . + (empty ($obsoleted) ? "" : "obsoleted = $sql_obsoleted, ") . + (empty ($size) ? "" : "filesize = $sql_size, ") . + (empty ($mtime) ? "" : "filemtime = $sql_mtime, ") . + "diskstatus = $sql_diskstatus"; + + // $fields = rtrim ($fields, ", "); + + $db->BeginTrans (); + + $db->exec ("select pk from files where filename = $sql_filename"); + $newfile = !$db->FirstRow (); + + if ($newfile) { + $db->exec ("insert into files (filename, diskstatus) values ($sql_filename, 0);"); + } + + $db->exec ("update files set $fields where filename = $sql_filename"); + + $db->Commit (); + + echo (($newfile ? "Added" : "Updated") . " file $directory/$filename " . + "($sql_etext_number $sql_fk_filetypes $sql_fk_compressions $sql_fk_encodings $sql_diskstatus $sql_obsoleted)\n"); + } + + // maybe insert book into books table + if (!empty ($etext_number)) { + $db->BeginTrans (); + + $sql_etext_number = $db->f ($etext_number, SQLINT); + $db->exec ("select * from books where pk = $sql_etext_number"); + + if ($db->FirstRow ()) { + $updatemode = $db->get ("updatemode", SQLINT); // 0 = auto, 1 = manual + } else { + $db->exec ("insert into books (pk) values ($sql_etext_number)"); + echo ("Inserted book $etext_number into database\n"); + } + + if ($updatemode == 0) { + if ($fk_encodings != "utf-8") { + iconv_set_encoding ("internal_encoding", "UTF-8"); + $converted = iconv (strtoupper ($fk_encodings), "UTF-8", $e); + if ($converted !== FALSE) { + $e = $converted; + } + } + $lines = preg_split ("/\n/", $e); + foreach ($lines as $line) { + if (empty ($line)) continue; + if (!preg_match ("/^(.*?):\s+(.*)$/", $line, $matches)) + continue; + list ($dummy, $key, $value) = $matches; // preg_split ("/:\s+/", $line); //FIXME + if (empty ($value)) continue; + + if (isset ($roles[$key])) { + list ($author, $born, $died, $role) = decode_author ($value); + $pk_author = insert_author ($author, $born, $died); + if ($key != "Author") { + $role = $roles[$key]; + } + if ($pk_author) { + $sql_fk_authors = $db->f ($pk_author, SQLINT); + $sql_fk_roles = $db->f ($role, SQLCHAR); + $db->exec ("select * from mn_books_authors " . + "where fk_books = $sql_etext_number and fk_authors = $sql_fk_authors " . + "and fk_roles = $sql_fk_roles"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_authors (fk_books, fk_authors, fk_roles) " . + "values ($sql_etext_number, $sql_fk_authors, $sql_fk_roles)"); + echo ("Added author '$author' role $role to book $etext_number\n"); + } + } + $cnt_authors++; + continue; + } + if ($key == "Title") { + insert_title ($etext_number, $value, 245); + $got_title = 1; + continue; + } + if ($key == "Alternate Title") { + insert_title ($etext_number, $value, 246); + continue; + } + if ($key == "Contents") { + insert_title ($etext_number, $value, 505); + continue; + } + if ($key == "Language") { + $lang = encode_language ($value); + if (!empty ($lang)) { + $sql_lang = $db->f ($lang, SQLCHAR); + $db->exec ("select * from mn_books_langs " . + "where fk_books = $sql_etext_number and fk_langs = $sql_lang"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_langs (fk_books, fk_langs) " . + "values ($sql_etext_number, $sql_lang)"); + } + } + continue; + } + if ($key == "Locc") { + $sql_locc = $db->f (strtoupper ($value), SQLCHAR); + $db->exec ("select * from mn_books_loccs " . + "where fk_books = $sql_etext_number and fk_loccs = $sql_locc"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_loccs (fk_books, fk_loccs) " . + "values ($sql_etext_number, $sql_locc)"); + } + continue; + } + if ($key == "Subject") { + $sql_subject = $db->f ($value, SQLCHAR); + $db->exec ("select pk from subjects where subject = $sql_subject"); + if (!$db->FirstRow ()) { + $db->exec ("insert into subjects (subject) values ($sql_subject)"); + $db->exec ("select pk from subjects where subject = $sql_subject"); + } + $pk_subjects = $db->Get ("pk", SQLINT); + $sql_fk_subjects = $db->f ($pk_subjects, SQLINT); + + $db->exec ("select * from mn_books_subjects " . + "where fk_books = $sql_etext_number and fk_subjects = $sql_fk_subjects"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_subjects (fk_books, fk_subjects) " . + "values ($sql_etext_number, $sql_fk_subjects)"); + } + continue; + } + if ($key == "Note") { + $sql_note = $db->f ($value, SQLCHAR); + $db->exec ("select * from attributes " . + "where fk_books = $sql_etext_number and text = $sql_note"); + if (!$db->FirstRow ()) { + $db->exec ("insert into attributes (fk_books, fk_attriblist, text) values ($sql_etext_number, 500, $sql_note)"); + } + continue; + } + if ($key == "Copyright") { + $sql_copyrighted = $db->f ($value, SQLINT); + $db->exec ("update books set copyrighted = $sql_copyrighted where pk = $sql_etext_number"); + continue; + } + if ($key == "Category") { + $sql_category = $db->f ($value, SQLCHAR); + $db->exec ("select pk from categories where category = $sql_category"); + if ($db->FirstRow ()) { + $fk_categories = $db->get ("pk", SQLINT); + $sql_fk_categories = $db->f ($fk_categories, SQLINT); + + $db->exec ("select * from mn_books_categories " . + "where fk_books = $sql_etext_number and fk_categories = $sql_fk_categories"); + if (!$db->FirstRow ()) { + $db->exec ("insert into mn_books_categories (fk_books, fk_categories) " . + "values ($sql_etext_number, $fk_categories)"); + } + } + continue; + } + if ($key == "Release-Date") { + if (strpos ($value, ',') === false) { + $vale = "1 $value"; + } + $release_date = strtotime ("$value"); + $sql_release_date = $db->f ($release_date, SQLDATE); + $db->exec ("update books set release_date = $sql_release_date where pk = $sql_etext_number"); + continue; + } + } + + // hack! makefiles.pl sorts filenames so that 8-bit ones come first + // this way we prefer titles etc. from 8-bit files over html and 7-bit files + if ($got_title) { + $db->exec ("update books set updatemode = 1 where pk = $sql_etext_number"); + } + + $db->Commit (); + } + } +} + +register_shutdown_function ('rollback_transaction'); +set_time_limit (0); + +$buffer = ""; +if ($hd = fopen ($importfilename, "r")) { + while (!feof ($hd)) { + $line = fgets ($hd); + if (preg_match ("/^---*[\r\n]*$/", $line)) { + process_section ($buffer); + $buffer = ""; + echo ("\n"); flush (); + } else { + $buffer .= $line; + } + } + process_section ($buffer); + fclose ($hd); +} + +?> diff --git a/catalog/admin/categories_list.php b/catalog/admin/categories_list.php new file mode 100644 index 0000000..937ec3f --- /dev/null +++ b/catalog/admin/categories_list.php @@ -0,0 +1,44 @@ +AddColumn ("$prefix=edit&fk_categories=#pk#\">Edit", + "$prefix=add\">Add", "left", "1%"); + $this->AddColumn ("$prefix=delete&fk_categories=#pk#\">Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("category", "Category"); + } +} + +$db = $config->db (); + +p ("Please enter the first few characters of the category (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. *human) +To see everything just enter *."); + +form_open (); +echo ("  \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from categories where category ilike '$filt%' order by category;"); + $table = new ListCategoriesTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/categories_list.php~ b/catalog/admin/categories_list.php~ new file mode 100644 index 0000000..ea55bb9 --- /dev/null +++ b/catalog/admin/categories_list.php~ @@ -0,0 +1,43 @@ +AddColumn ("$prefix=edit&fk_categories=#pk#\">Edit", + "$prefix=add\">Add", "left", "1%"); + $this->AddColumn ("$prefix=delete&fk_categories=#pk#\">Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("category", "Category"); + } +} + +$db = $config->db (); + +p ("Please enter the first few characters of the category (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. *human) +To see everything just enter *."); + +form_open (); +echo ("  \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from categories where category ilike '$filt%' order by category;"); + $table = new ListCategoriesTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/category.php b/catalog/admin/category.php new file mode 100644 index 0000000..3768229 --- /dev/null +++ b/catalog/admin/category.php @@ -0,0 +1,92 @@ +AddColumn ("#pk#", + "Etext Nr.", "right", "1*"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddSimpleColumn ("title", "Title"); + $this->limit = 25; + $this->relay = array ("fk_categories", "mode", "filter"); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_categories"); +getstr ("filter"); + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_categories " . + "where fk_categories = $fk_categories"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + $f->SubCaption ("Warning: There are $cnt books related to this category. "); + } + $f->SubCaption ("You are about to delete this category."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("category", "category", "Category", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from categories where pk = $fk_categories"); +} +$f->Hidden ("fk_categories"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into categories " . $sql)) { + msg ("Category added !"); + } else { + error_msg ("Could not add category!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update categories set " . $sql . "where pk = $fk_categories")) { + msg ("Category modified !"); + } else { + error_msg ("Could not modify category !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_books_categories where fk_categories = $fk_categories"); + if ($db->Exec ("delete from categories where pk = $fk_categories")) { + msg ("Category deleted !"); + } else { + error_msg ("Could not delete category !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + echo ("

" . + "Back to Category

\n\n"); + } +} else { + $f->Output ($caption, $caption); +} + +echo ("

" . + "Back to Category List

\n\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/category.php~ b/catalog/admin/category.php~ new file mode 100644 index 0000000..253b3e3 --- /dev/null +++ b/catalog/admin/category.php~ @@ -0,0 +1,91 @@ +AddColumn ("#pk#", + "Etext Nr.", "right", "1*"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddSimpleColumn ("title", "Title"); + $this->limit = 25; + $this->relay = array ("fk_categories", "mode", "filter"); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_categories"); +getstr ("filter"); + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_categories " . + "where fk_categories = $fk_categories"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + $f->SubCaption ("Warning: There are $cnt books related to this category. "); + } + $f->SubCaption ("You are about to delete this category."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("category", "category", "Category", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from categories where pk = $fk_categories"); +} +$f->Hidden ("fk_categories"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into categories " . $sql)) { + msg ("Category added !"); + } else { + error_msg ("Could not add category!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update categories set " . $sql . "where pk = $fk_categories")) { + msg ("Category modified !"); + } else { + error_msg ("Could not modify category !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_books_categories where fk_categories = $fk_categories"); + if ($db->Exec ("delete from categories where pk = $fk_categories")) { + msg ("Category deleted !"); + } else { + error_msg ("Could not delete category !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + echo ("

" . + "Back to Category

\n\n"); + } +} else { + $f->Output ($caption, $caption); +} + +echo ("

" . + "Back to Category List

\n\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/charset_guesser.php b/catalog/admin/charset_guesser.php new file mode 100644 index 0000000..5b1bb61 --- /dev/null +++ b/catalog/admin/charset_guesser.php @@ -0,0 +1,96 @@ +db (); +getstr ("file"); +getint ("samples", 10); + +pageheader ("Encoding Guesses for $file"); + +$root = "/public/ftp/pub/docs/books/gutenberg/"; + +$path = realpath ("$root$file"); + +if (!preg_match ("|^$root|", $path) || (!$hd = fopen ($path, "r"))) { + // serve only files below root + header("HTTP/1.0 404 Not Found"); + echo ("I see no such file here\n"); + exit; +} + +// get some words with funny characters + +$data = file_get_contents ($path); +preg_match_all ("/\b.{0,20}[\x80-\xFF].{0,20}\b/s", $data, $matches); +$found_samples = count ($matches[0]); + +if ($found_samples == 0) { + echo ("

No non-ascii characters found.

"); + pagefooter (); + exit (); +} + +$more_samples = $samples > 0 && $found_samples > $samples; + +$words = join ("\n", $samples ? array_slice ($matches[0], 0, $samples) : $matches[0]); + +// convert those words to all known encodings + +$encodings = array (); +$db->exec ("select pk from encodings order by pk"); +if ($db->FirstRow ()) { + do { + $encodings[] = $db->Get ("pk"); + } while ($db->NextRow ()); +} + +$me = $_SERVER['PATH_INFO'] . htmlspecialchars ("?file=$file"); +if ($more_samples) { + $caption = "Samples (first $samples of $found_samples found) show all"; +} else { + $caption = "Samples (all $found_samples found)"; + if ($found_samples > 10) + $caption .= " show only first 10"; +} + +echo ("\n"); + +function hex ($c) { + return sprintf ('\x%2X', ord ($c)); +} + +$sample = htmlspecialchars (@preg_replace ("/[\x80-\xFF]/e", 'hex ($0)', $words)); +$sample = preg_replace ("/\n/", "
", $sample); +echo ("\n"); + +mb_regex_encoding ("UTF-8"); +mb_ereg_search_init ("[\x80-\x9F]"); + +foreach ($encodings as $enc) { + $wordslen = strlen ($words); + $sample = @iconv ($enc, "UTF-8", $words); + if ($sample) { + if (!mb_ereg ("[\200-\237]", $sample)) { + if (iconv_strlen ($sample, 'UTF-8') == $wordslen) { + $sample = preg_replace ("/\n/", "
", htmlspecialchars ($sample)); + echo ("\n"); + } + } + } +} + +echo ("
Encoding$caption
hex-escaped$sample
$enc$sample
"); + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/charset_guesser.php~ b/catalog/admin/charset_guesser.php~ new file mode 100644 index 0000000..2aa7bb5 --- /dev/null +++ b/catalog/admin/charset_guesser.php~ @@ -0,0 +1,95 @@ +db (); +getstr ("file"); +getint ("samples", 10); + +pageheader ("Encoding Guesses for $file"); + +$root = "/public/ftp/pub/docs/books/gutenberg/"; + +$path = realpath ("$root$file"); + +if (!preg_match ("|^$root|", $path) || (!$hd = fopen ($path, "r"))) { + // serve only files below root + header("HTTP/1.0 404 Not Found"); + echo ("I see no such file here\n"); + exit; +} + +// get some words with funny characters + +$data = file_get_contents ($path); +preg_match_all ("/\b.{0,20}[\x80-\xFF].{0,20}\b/s", $data, $matches); +$found_samples = count ($matches[0]); + +if ($found_samples == 0) { + echo ("

No non-ascii characters found.

"); + pagefooter (); + exit (); +} + +$more_samples = $samples > 0 && $found_samples > $samples; + +$words = join ("\n", $samples ? array_slice ($matches[0], 0, $samples) : $matches[0]); + +// convert those words to all known encodings + +$encodings = array (); +$db->exec ("select pk from encodings order by pk"); +if ($db->FirstRow ()) { + do { + $encodings[] = $db->Get ("pk"); + } while ($db->NextRow ()); +} + +$me = $_SERVER['PATH_INFO'] . htmlspecialchars ("?file=$file"); +if ($more_samples) { + $caption = "Samples (first $samples of $found_samples found) show all"; +} else { + $caption = "Samples (all $found_samples found)"; + if ($found_samples > 10) + $caption .= " show only first 10"; +} + +echo ("\n"); + +function hex ($c) { + return sprintf ('\x%2X', ord ($c)); +} + +$sample = htmlspecialchars (@preg_replace ("/[\x80-\xFF]/e", 'hex ($0)', $words)); +$sample = preg_replace ("/\n/", "
", $sample); +echo ("\n"); + +mb_regex_encoding ("UTF-8"); +mb_ereg_search_init ("[\x80-\x9F]"); + +foreach ($encodings as $enc) { + $wordslen = strlen ($words); + $sample = @iconv ($enc, "UTF-8", $words); + if ($sample) { + if (!mb_ereg ("[\200-\237]", $sample)) { + if (iconv_strlen ($sample, 'UTF-8') == $wordslen) { + $sample = preg_replace ("/\n/", "
", htmlspecialchars ($sample)); + echo ("\n"); + } + } + } +} + +echo ("
Encoding$caption
hex-escaped$sample
$enc$sample
"); + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/check_urls.php b/catalog/admin/check_urls.php new file mode 100644 index 0000000..19d8dd1 --- /dev/null +++ b/catalog/admin/check_urls.php @@ -0,0 +1,84 @@ +db (); + +$cnt = 0; + +$db->exec ("select author, url from authors, author_urls where authors.pk = author_urls.fk_authors order by url"); + +if ($db->FirstRow ()) { + do { + $url = $db->get ("url", SQLCHAR); + $author = $db->get ("author", SQLCHAR); + + sleep (1); + + if (!preg_match ("!^http://(.*?)(/.*)$!", $url, $matches)) { + echo ("$author\nNot a http url: $url\n"); + $cnt++; + continue; + } + + $host = $matches[1]; + $path = $matches[2]; + + $sock = @fsockopen ($host, 80, $errno, $errstr, 120); + if (!$sock) { + echo ("$author\nHost $host unreachable! $errstr ($errno)\n"); + $cnt++; + continue; + } + + $request = "HEAD $path HTTP/1.0\r\nHost: $host\r\n\r\n"; + + // echo ($request); + + fwrite ($sock, $request); + + $headers = ""; + while ($str = trim (fgets ($sock, 4096))) + $headers .= "$str\n"; + + fclose ($sock); + + if (!preg_match ("!^HTTP/\d\.\d\s+(\d+)!", $headers, $matches)) { + echo ("$author\nGot bogus response from $host!\n\n($headers)\n\n"); + $cnt++; + continue; + } + + $code = intval ($matches[1]); + + if ($code == 200) { + continue; + } + if ($code >= 300 && $code < 400) { + echo ("$author\n$url Redirected $code"); + if (preg_match ("!^Location:\s+(.*)$!im", $headers, $matches)) { + $location = $matches[1]; + echo (" to $location"); + } + echo ("\n"); + continue; + } + + echo ("$author\n$url Error $code!\n"); + $cnt++; + + } while ($db->NextRow ()); +} + +if ($cnt) { + echo ("$cnt urls failed!!\n"); + return 1; +} + +return 0; + +?> diff --git a/catalog/admin/check_urls.php~ b/catalog/admin/check_urls.php~ new file mode 100644 index 0000000..021c84c --- /dev/null +++ b/catalog/admin/check_urls.php~ @@ -0,0 +1,83 @@ +db (); + +$cnt = 0; + +$db->exec ("select author, url from authors, author_urls where authors.pk = author_urls.fk_authors order by url"); + +if ($db->FirstRow ()) { + do { + $url = $db->get ("url", SQLCHAR); + $author = $db->get ("author", SQLCHAR); + + sleep (1); + + if (!preg_match ("!^http://(.*?)(/.*)$!", $url, $matches)) { + echo ("$author\nNot a http url: $url\n"); + $cnt++; + continue; + } + + $host = $matches[1]; + $path = $matches[2]; + + $sock = @fsockopen ($host, 80, $errno, $errstr, 120); + if (!$sock) { + echo ("$author\nHost $host unreachable! $errstr ($errno)\n"); + $cnt++; + continue; + } + + $request = "HEAD $path HTTP/1.0\r\nHost: $host\r\n\r\n"; + + // echo ($request); + + fwrite ($sock, $request); + + $headers = ""; + while ($str = trim (fgets ($sock, 4096))) + $headers .= "$str\n"; + + fclose ($sock); + + if (!preg_match ("!^HTTP/\d\.\d\s+(\d+)!", $headers, $matches)) { + echo ("$author\nGot bogus response from $host!\n\n($headers)\n\n"); + $cnt++; + continue; + } + + $code = intval ($matches[1]); + + if ($code == 200) { + continue; + } + if ($code >= 300 && $code < 400) { + echo ("$author\n$url Redirected $code"); + if (preg_match ("!^Location:\s+(.*)$!im", $headers, $matches)) { + $location = $matches[1]; + echo (" to $location"); + } + echo ("\n"); + continue; + } + + echo ("$author\n$url Error $code!\n"); + $cnt++; + + } while ($db->NextRow ()); +} + +if ($cnt) { + echo ("$cnt urls failed!!\n"); + return 1; +} + +return 0; + +?> diff --git a/catalog/admin/checklink.php b/catalog/admin/checklink.php new file mode 100644 index 0000000..ed60987 --- /dev/null +++ b/catalog/admin/checklink.php @@ -0,0 +1,44 @@ +db (); + +$db->exec ("select * from files where fk_filetypes = 'html' and fk_compressions = 'none' order by filename"); + +if ($db->FirstRow ()) { + do { + $filename = $db->get ("filename", SQLCHAR); + + echo ("Checking $filename ..."); + + $url = "http://$config->domain/dirs/$filename"; + $output = `/public/vhost/g/gutenberg/private/local/bin/checklink -q -s --broken $url`; + + if (preg_match ("/broken links/i", $output)) { + echo (" ERRORS!\n$output\n"); + $validator = "http://validator.w3.org/checklink?uri=" . urlencode ($url) . "&hide_type=all&depth=&check=Check"; + + mail ("marcello@perathoner.de", "Broken links in $filename", + "Validator url:\n\n$validator\n\nValidator output was:\n$output", + "From: linkchecker@gutenberg.org\r\n" . + "Reply-To: webmaster@gutenberg.org\r\n"); + + } else { + echo (" OK\n"); + } + + } while ($db->NextRow ()); +} + +?> diff --git a/catalog/admin/checklink.php~ b/catalog/admin/checklink.php~ new file mode 100644 index 0000000..1acc604 --- /dev/null +++ b/catalog/admin/checklink.php~ @@ -0,0 +1,43 @@ +db (); + +$db->exec ("select * from files where fk_filetypes = 'html' and fk_compressions = 'none' order by filename"); + +if ($db->FirstRow ()) { + do { + $filename = $db->get ("filename", SQLCHAR); + + echo ("Checking $filename ..."); + + $url = "http://$config->domain/dirs/$filename"; + $output = `/public/vhost/g/gutenberg/private/local/bin/checklink -q -s --broken $url`; + + if (preg_match ("/broken links/i", $output)) { + echo (" ERRORS!\n$output\n"); + $validator = "http://validator.w3.org/checklink?uri=" . urlencode ($url) . "&hide_type=all&depth=&check=Check"; + + mail ("marcello@perathoner.de", "Broken links in $filename", + "Validator url:\n\n$validator\n\nValidator output was:\n$output", + "From: linkchecker@gutenberg.org\r\n" . + "Reply-To: webmaster@gutenberg.org\r\n"); + + } else { + echo (" OK\n"); + } + + } while ($db->NextRow ()); +} + +?> diff --git a/catalog/admin/chmod-cache.php b/catalog/admin/chmod-cache.php new file mode 100644 index 0000000..9bd124b --- /dev/null +++ b/catalog/admin/chmod-cache.php @@ -0,0 +1,19 @@ +start ...

'); +flush (); + +/* +for ($i = 0; $i < 31000; $i++) { + chmod ("/public/vhost/g/gutenberg/html/cache/bibrec/$i", 0777); + if (($i % 100) == 0) { + echo ("

$i

"); + flush (); + } +} +*/ + +echo (`chmod -R 777 /public/vhost/g/gutenberg/html/cache/wiki/*`); + +echo ('

done

'); + +?> diff --git a/catalog/admin/cp.php b/catalog/admin/cp.php new file mode 100644 index 0000000..ba5694f --- /dev/null +++ b/catalog/admin/cp.php @@ -0,0 +1,13 @@ + diff --git a/catalog/admin/cp.php~ b/catalog/admin/cp.php~ new file mode 100644 index 0000000..ce7480d --- /dev/null +++ b/catalog/admin/cp.php~ @@ -0,0 +1,12 @@ + diff --git a/catalog/admin/delete-o-matic.php b/catalog/admin/delete-o-matic.php new file mode 100644 index 0000000..4b68fad --- /dev/null +++ b/catalog/admin/delete-o-matic.php @@ -0,0 +1,115 @@ +db (); +$db->logger = new logger (); + +echo ("Initializing ...\n"); + +register_shutdown_function ('rollback_transaction'); +set_time_limit (0); + +$cnt = 0; +$db->Exec ("select filename from files where diskstatus != 5 order by filename"); +if ($db->FirstRow ()) { + do { + $files[$db->Get ("filename", SQLCHAR)] = 0; + $cnt++; + } while ($db->NextRow ()); +} + +echo ("$cnt files in database.\n"); + +echo ("Stat-ing files ...\n"); + +$cnt = 0; +$gonecnt = 0; +foreach ($files as $filename => $value) { + if ($filename[0] == '/') { + if (@stat ($filename) === FALSE) { + $gone[$filename] = 1; + $gonecnt++; + echo ("Gone: $filename\n"); + } + } elseif (preg_match ('/^(cache|masters)\//', $filename)) { + if (@stat ("$config->documentroot/$filename") === FALSE) { + $gone[$filename] = 1; + $gonecnt++; + echo ("Gone: $config->documentroot//$filename\n"); + } + } else { + if (@stat ("$config->filesroot/$filename") === FALSE) { + $gone[$filename] = 1; + $gonecnt++; + echo ("Gone: $config->filesroot//$filename\n"); + } + } + $cnt++; + if (($cnt % 100000) == 0) { + echo ("Stat: $cnt gone: $gonecnt\n"); + } + if ($gonecnt > 10000) { + echo ("Gone over 10.000 files!\nDeleted nothing. Check for errors."); + die (); + } +} + +$files = null; +echo ("Gone: $gonecnt files\n"); + +// stat everything again, maybe nfs is flaky today +for ($i = 0; $i < 10; $i++) { + if (!$gonecnt) + break; + echo ("Waiting ...\n"); + sleep (600); + echo ("Re-stat-ing: $gonecnt files\n"); + clearstatcache (); + foreach ($gone as $filename => $value) { + if ($value == 1) { + if (preg_match ('/^cache\//', $filename)) { + if (@stat ("$config->documentroot/$filename") !== FALSE) { + $gone[$filename] = 0; + $gonecnt--; + } + } else { + if (@stat ("$config->filesroot/$filename") !== FALSE) { + $gone[$filename] = 0; + $gonecnt--; + } + } + } + } +} + +if ($gonecnt) { + echo ("Deleting: $gonecnt files ...\n"); + + foreach ($gone as $filename => $value) { + if ($value == 1) { + echo ("Marking as deleted: $filename\n"); + $esc_filename = addslashes($filename); + $db->exec ("update files set diskstatus = 5 where filename = '$esc_filename'"); + + $infofile = "$config->privateroot/fileinfo/$filename.info"; + @unlink ($infofile); + } + } +} + +echo ("Done.\n"); + +?> diff --git a/catalog/admin/delete-o-matic.php~ b/catalog/admin/delete-o-matic.php~ new file mode 100644 index 0000000..65c6745 --- /dev/null +++ b/catalog/admin/delete-o-matic.php~ @@ -0,0 +1,114 @@ +db (); +$db->logger = new logger (); + +echo ("Initializing ...\n"); + +register_shutdown_function ('rollback_transaction'); +set_time_limit (0); + +$cnt = 0; +$db->Exec ("select filename from files where diskstatus != 5 order by filename"); +if ($db->FirstRow ()) { + do { + $files[$db->Get ("filename", SQLCHAR)] = 0; + $cnt++; + } while ($db->NextRow ()); +} + +echo ("$cnt files in database.\n"); + +echo ("Stat-ing files ...\n"); + +$cnt = 0; +$gonecnt = 0; +foreach ($files as $filename => $value) { + if ($filename[0] == '/') { + if (@stat ($filename) === FALSE) { + $gone[$filename] = 1; + $gonecnt++; + echo ("Gone: $filename\n"); + } + } elseif (preg_match ('/^(cache|masters)\//', $filename)) { + if (@stat ("$config->documentroot/$filename") === FALSE) { + $gone[$filename] = 1; + $gonecnt++; + echo ("Gone: $config->documentroot//$filename\n"); + } + } else { + if (@stat ("$config->filesroot/$filename") === FALSE) { + $gone[$filename] = 1; + $gonecnt++; + echo ("Gone: $config->filesroot//$filename\n"); + } + } + $cnt++; + if (($cnt % 100000) == 0) { + echo ("Stat: $cnt gone: $gonecnt\n"); + } + if ($gonecnt > 10000) { + echo ("Gone over 10.000 files!\nDeleted nothing. Check for errors."); + die (); + } +} + +$files = null; +echo ("Gone: $gonecnt files\n"); + +// stat everything again, maybe nfs is flaky today +for ($i = 0; $i < 10; $i++) { + if (!$gonecnt) + break; + echo ("Waiting ...\n"); + sleep (600); + echo ("Re-stat-ing: $gonecnt files\n"); + clearstatcache (); + foreach ($gone as $filename => $value) { + if ($value == 1) { + if (preg_match ('/^cache\//', $filename)) { + if (@stat ("$config->documentroot/$filename") !== FALSE) { + $gone[$filename] = 0; + $gonecnt--; + } + } else { + if (@stat ("$config->filesroot/$filename") !== FALSE) { + $gone[$filename] = 0; + $gonecnt--; + } + } + } + } +} + +if ($gonecnt) { + echo ("Deleting: $gonecnt files ...\n"); + + foreach ($gone as $filename => $value) { + if ($value == 1) { + echo ("Marking as deleted: $filename\n"); + $esc_filename = addslashes($filename); + $db->exec ("update files set diskstatus = 5 where filename = '$esc_filename'"); + + $infofile = "$config->privateroot/fileinfo/$filename.info"; + @unlink ($infofile); + } + } +} + +echo ("Done.\n"); + +?> diff --git a/catalog/admin/dupl_attrib_list.php b/catalog/admin/dupl_attrib_list.php new file mode 100644 index 0000000..651a404 --- /dev/null +++ b/catalog/admin/dupl_attrib_list.php @@ -0,0 +1,27 @@ +db (); +$db->logger = new logger (); + +pageheader("Books with duplicate MARC fields"); + +class DuplAttribTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#name#", "MARC Field"); + $this->AddColumn("#cnt#", "# of fields per book"); + $this->AddColumn("#count#", "# of books"); + } +} +p("Click on the MARC Fields to see a list of the actual duplicates."); +$db->Exec("select name, code, cnt, count(cnt) from (select fk_attriblist as code, count(fk_attriblist) as cnt from attributes group by fk_books, fk_attriblist having count(fk_attriblist)>1) as foo join attriblist on code=attriblist.pk group by attriblist.pk, attriblist.name, code, cnt order by code"); +$table = new DuplAttribTable(); +$table->PrintTable($db, "Duplicate MARC Fields"); + +pagefooter(); diff --git a/catalog/admin/dupl_attrib_list.php~ b/catalog/admin/dupl_attrib_list.php~ new file mode 100644 index 0000000..34dce11 --- /dev/null +++ b/catalog/admin/dupl_attrib_list.php~ @@ -0,0 +1,26 @@ +db (); +$db->logger = new logger (); + +pageheader("Books with duplicate MARC fields"); + +class DuplAttribTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#name#", "MARC Field"); + $this->AddColumn("#cnt#", "# of fields per book"); + $this->AddColumn("#count#", "# of books"); + } +} +p("Click on the MARC Fields to see a list of the actual duplicates."); +$db->Exec("select name, code, cnt, count(cnt) from (select fk_attriblist as code, count(fk_attriblist) as cnt from attributes group by fk_books, fk_attriblist having count(fk_attriblist)>1) as foo join attriblist on code=attriblist.pk group by attriblist.pk, attriblist.name, code, cnt order by code"); +$table = new DuplAttribTable(); +$table->PrintTable($db, "Duplicate MARC Fields"); + +pagefooter(); diff --git a/catalog/admin/dupl_attribs.php b/catalog/admin/dupl_attribs.php new file mode 100644 index 0000000..3904c63 --- /dev/null +++ b/catalog/admin/dupl_attribs.php @@ -0,0 +1,34 @@ +db (); +$db->logger = new logger (); + +getint("fk_attriblist"); +getint("cnt"); + +$db->Exec("select name from attriblist where pk=$fk_attriblist"); +$attr_name = $db->Get("name"); + +pageheader("Books with $cnt of the '$attr_name' field"); + + +class DuplAttribDetailTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#fk_books#", "Etext #"); + $this->AddColumn("#text#", "Text of field"); + } +} +$table= new DuplAttribDetailTable(); +$db->Exec ("select fk_books, text from attributes where fk_attriblist=$fk_attriblist and fk_books in (select fk_books from attributes where fk_attriblist=$fk_attriblist group by fk_books, fk_attriblist having count(fk_attriblist)=$cnt) order by fk_books"); +$table->PrintTable($db, ""); +/* TODO: Convert $cnt to words, i.e. "five" not "5" */ + +p("Return to list"); + +pagefooter(); diff --git a/catalog/admin/dupl_attribs.php~ b/catalog/admin/dupl_attribs.php~ new file mode 100644 index 0000000..42b8c5e --- /dev/null +++ b/catalog/admin/dupl_attribs.php~ @@ -0,0 +1,33 @@ +db (); +$db->logger = new logger (); + +getint("fk_attriblist"); +getint("cnt"); + +$db->Exec("select name from attriblist where pk=$fk_attriblist"); +$attr_name = $db->Get("name"); + +pageheader("Books with $cnt of the '$attr_name' field"); + + +class DuplAttribDetailTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#fk_books#", "Etext #"); + $this->AddColumn("#text#", "Text of field"); + } +} +$table= new DuplAttribDetailTable(); +$db->Exec ("select fk_books, text from attributes where fk_attriblist=$fk_attriblist and fk_books in (select fk_books from attributes where fk_attriblist=$fk_attriblist group by fk_books, fk_attriblist having count(fk_attriblist)=$cnt) order by fk_books"); +$table->PrintTable($db, ""); +/* TODO: Convert $cnt to words, i.e. "five" not "5" */ + +p("Return to list"); + +pagefooter(); diff --git a/catalog/admin/empty_authors.php b/catalog/admin/empty_authors.php new file mode 100644 index 0000000..a8fdac0 --- /dev/null +++ b/catalog/admin/empty_authors.php @@ -0,0 +1,32 @@ +db (); + +$db->logger = new logger (); + +class AuthorsBirthDeathDeletionTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "Delete", "", "narrow"); + $this->AddColumn("" . + "#author#", "Author"); + $this->AddSimpleColumn("born_floor", "Birth"); + $this->AddSimpleColumn("died_floor", "Death"); + } +} + +pageheader("Authors with no books"); + +$table = new AuthorsBirthDeathDeletionTable (); +$db->Exec("select distinct pk, author, born_floor, died_floor " . + "from authors left join mn_books_authors " . + "on fk_authors=authors.pk where fk_books is null " . + "order by author, pk"); +$table->PrintTable($db, "Authors with no books linked"); + +pagefooter(); diff --git a/catalog/admin/empty_authors.php~ b/catalog/admin/empty_authors.php~ new file mode 100644 index 0000000..9a1e285 --- /dev/null +++ b/catalog/admin/empty_authors.php~ @@ -0,0 +1,31 @@ +db (); + +$db->logger = new logger (); + +class AuthorsBirthDeathDeletionTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "Delete", "", "narrow"); + $this->AddColumn("" . + "#author#", "Author"); + $this->AddSimpleColumn("born_floor", "Birth"); + $this->AddSimpleColumn("died_floor", "Death"); + } +} + +pageheader("Authors with no books"); + +$table = new AuthorsBirthDeathDeletionTable (); +$db->Exec("select distinct pk, author, born_floor, died_floor " . + "from authors left join mn_books_authors " . + "on fk_authors=authors.pk where fk_books is null " . + "order by author, pk"); +$table->PrintTable($db, "Authors with no books linked"); + +pagefooter(); diff --git a/catalog/admin/file.php b/catalog/admin/file.php new file mode 100644 index 0000000..6e78b21 --- /dev/null +++ b/catalog/admin/file.php @@ -0,0 +1,71 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); + +getint ("fk_files"); +getint ("fk_books"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this file."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + if (ismode ("add")) { + $f->SQLInject ("fk_books", "fk_books", SQLINT); + } + $f->Text ("filename", "filename", "Filename", SQLCHAR, 80, 240, true); + $f->Text ("fk_books", "fk_books", "Etext-Nr.", SQLINT, 20, 80, false); + $f->Text ("edition", "edition", "Edition", SQLINT, 20, 80, false); + $f->Text ("filemtime", "filemtime", "File Modification Time", SQLDATE, 20, 20, false); + $f->CheckBox ("obsoleted", "obsoleted", "Obsoleted", SQLINT); + $f->SQLSelect ("fk_filetypes", "fk_filetypes", "File Type", SQLCHAR, 40, 80, true, + "select pk as value, filetype as caption from filetypes order by filetype"); + $f->SQLSelect ("fk_compressions", "fk_compressions", "Compression", SQLCHAR, 40, 80, true, + "select pk as value, compression as caption from compressions order by compression"); + $f->SQLSelect ("fk_encodings", "fk_encodings", "Encoding", SQLCHAR, 40, 80, false, + "select null as value, 'unknown' as caption union " . + "select pk as value, pk as caption from encodings order by caption"); + $f->Text ("filesize", "filesize", "File Size", SQLINT, 20, 80, false); + $f->TextArea ("note", "note", "Note", SQLCHAR, 4, 80, false); + $f->LoadData ("select * from files where pk = $fk_files"); +} +$f->Hidden ("fk_files"); +$f->Hidden ("fk_books"); +$f->Hidden ("filemask"); + +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update files set " . $sql . "where pk = $fk_files")) { + msg ("File modified !"); + } else { + error_msg ("Could not modify file !"); + } + } +} + +if (isupdate ()) { + getint ("fk_books"); + getstr ("filemask"); + echo ("

Back to Book Files

\n\n"); +} else { + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/file.php~ b/catalog/admin/file.php~ new file mode 100644 index 0000000..6ccd451 --- /dev/null +++ b/catalog/admin/file.php~ @@ -0,0 +1,70 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); + +getint ("fk_files"); +getint ("fk_books"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this file."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + if (ismode ("add")) { + $f->SQLInject ("fk_books", "fk_books", SQLINT); + } + $f->Text ("filename", "filename", "Filename", SQLCHAR, 80, 240, true); + $f->Text ("fk_books", "fk_books", "Etext-Nr.", SQLINT, 20, 80, false); + $f->Text ("edition", "edition", "Edition", SQLINT, 20, 80, false); + $f->Text ("filemtime", "filemtime", "File Modification Time", SQLDATE, 20, 20, false); + $f->CheckBox ("obsoleted", "obsoleted", "Obsoleted", SQLINT); + $f->SQLSelect ("fk_filetypes", "fk_filetypes", "File Type", SQLCHAR, 40, 80, true, + "select pk as value, filetype as caption from filetypes order by filetype"); + $f->SQLSelect ("fk_compressions", "fk_compressions", "Compression", SQLCHAR, 40, 80, true, + "select pk as value, compression as caption from compressions order by compression"); + $f->SQLSelect ("fk_encodings", "fk_encodings", "Encoding", SQLCHAR, 40, 80, false, + "select null as value, 'unknown' as caption union " . + "select pk as value, pk as caption from encodings order by caption"); + $f->Text ("filesize", "filesize", "File Size", SQLINT, 20, 80, false); + $f->TextArea ("note", "note", "Note", SQLCHAR, 4, 80, false); + $f->LoadData ("select * from files where pk = $fk_files"); +} +$f->Hidden ("fk_files"); +$f->Hidden ("fk_books"); +$f->Hidden ("filemask"); + +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update files set " . $sql . "where pk = $fk_files")) { + msg ("File modified !"); + } else { + error_msg ("Could not modify file !"); + } + } +} + +if (isupdate ()) { + getint ("fk_books"); + getstr ("filemask"); + echo ("

Back to Book Files

\n\n"); +} else { + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/files.php b/catalog/admin/files.php new file mode 100644 index 0000000..d9fabba --- /dev/null +++ b/catalog/admin/files.php @@ -0,0 +1,206 @@ +db (); +getint ("fk_books"); +getstr ("filemask"); + +pageheader ("Files for EBook #$fk_books"); + +p ("Careful! If you change the Ebook number you link the file to a different Ebook."); +p ("Note: you cannot add files to the database. " . + "That is done automagically by a nightly cron job."); + +p ("Goto Edit Book Page — " . + "etext/${fk_books}\">Goto Bibrec Page"); + +function mk_options ($name, $options, $option) { + $ret = ""; + foreach ($options as $value => $opt) { + $selected = ($opt == $option) ? " selected=\"selected\"" : ""; + $ret .= "\n"; + } + return "\n"; +} + +$filetypes[null] = "unknown"; +$db->Exec ("select * from filetypes order by filetype"); +if ($db->FirstRow ()) { + do { + $filetypes[$db->Get ("pk")] = $db->Get ("filetype"); + } while ($db->NextRow ()); +} + +$compressions[null] = "unknown"; +$db->Exec ("select * from compressions order by compression"); +if ($db->FirstRow ()) { + do { + $compressions[$db->Get ("pk")] = $db->Get ("compression"); + } while ($db->NextRow ()); +} + +$encodings[null] = "unknown"; +$db->Exec ("select * from encodings order by pk"); +if ($db->FirstRow ()) { + do { + $encodings[$db->Get ("pk")] = $db->Get ("pk"); + } while ($db->NextRow ()); +} + +class HeadColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "", "narrow"); + } + function Data ($db) { + $filename = $db->get ("filename"); + if (preg_match ("/\.zip$/i", $filename)) + return "Dir"; + return "Head"; + } +} + +class CharsetColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "", "narrow"); + } + function Data ($db) { + $filename = $db->get ("filename"); + if (preg_match ("/\.zip$/i", $filename)) + return ""; + return "Guess"; + } +} + +class SizeColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Size", "pgdbfilessize"); + } + function Header () { + return "Size"; + } + function Data ($db) { + return "" . human_readable_size ($db->get ("filesize")) . ""; + } +} + +class FiletypeColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "File Type", "pgdbfilesfiletype"); + } + function Data ($db) { + global $filetypes; + return "" . mk_options ("fk_filetypes", $filetypes, $db->get ("filetype")) . ""; + } +} + +class CompressionColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Compression", "pgdbfilescompression"); + } + function Data ($db) { + global $compressions; + return "" . mk_options ("fk_compressions", $compressions, $db->get ("compression")) . ""; + } +} + +class EncodingColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Encoding", "pgdbfilesencoding"); + } + function Data ($db) { + global $encodings; + return "" . mk_options ("fk_encodings", $encodings, $db->get ("fk_encodings")) . ""; + } +} + +class ObsoletedColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Obs.", "pgdbfilesobsoleted"); + } + function Data ($db) { + $obs = $db->get ("obsoleted", SQLINT) ? " checked=\"checked\"" : ""; + $pk = $db->get ("pk", SQLINT); + return ""; + } +} + +form_open_get (); +echo ("Enter Perl RegExp: eg. /12345/"); +form_relay ("fk_books"); +form_submit ("Reload"); +form_close (); + +// Files for book +$prefix = "AddColumn ("", "", "narrow"); +$t->AddColumn ("$prefix=edit&fk_files=#pk#\">Edit", "", "narrow"); +$t->AddColumnObject (new HeadColumn ()); +$t->AddColumn ("Bug", "", "narrow"); +$t->AddColumn ("downloadbase/#filename#\">#filename#" . + "", + "Filename"); +$t->AddColumn ("" . + "", "EBook"); +$t->AddColumn ("", "Edition"); +$t->AddColumnObject (new ObsoletedColumn ()); +$t->AddColumnObject (new FiletypeColumn ()); +$t->AddColumnObject (new EncodingColumn ()); +$t->AddColumnObject (new CharsetColumn ()); +$t->AddColumnObject (new CompressionColumn ()); +$t->AddColumnObject (new SizeColumn ()); + +///////////////////////////////////////////////////////////////////////////////// +// Generate list of candidate files +// + +/*if (empty ($filemask)) { + if ($fk_books > 10000) { + $filemask = "/${fk_books}[.-]"; + } else { + $db->Exec ("select * from books where pk = $fk_books"); + $filemask = $db->Get ("filemask"); + if (!empty ($filemask)) { + $filemask = preg_replace ("/\./", "\\.", $filemask); + $filemask = preg_replace ("/x+/", ".*", $filemask); + $filemask = preg_replace ("/^[?]/", "[78]", $filemask); + } + } +}*/ + +$sql = "select files.pk as pk, fk_books, filename, edition, obsoleted, filetype, " . + "compression, fk_encodings, filesize " . + "from files left join filetypes on files.fk_filetypes = filetypes.pk " . + "left join compressions on files.fk_compressions = compressions.pk " . + "where " . (empty ($filemask) ? "" : "filename ~ '$filemask' or ") . + "(fk_books = $fk_books and diskstatus = 0) " . + "order by (fk_books = $fk_books) desc, obsoleted, " . + "filetype, fk_encodings, compression, filename;"; + +$db->exec ($sql); + +form_open ("files2"); +$t->limit = 100; +$t->PrintTable ($db, "Files Linked to Book $fk_books or Matching RegExp: $filemask", "pgdbfiles"); +form_relay ("fk_books"); +form_relay ("filemask"); +form_submit ("Update Checked File Entries"); +form_close (); + +p ("To be implemented: functions for viewing bottom n lines from file, check +for character encoding, diff files, look into zips. In my copious free time."); + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/files.php~ b/catalog/admin/files.php~ new file mode 100644 index 0000000..4a21489 --- /dev/null +++ b/catalog/admin/files.php~ @@ -0,0 +1,205 @@ +db (); +getint ("fk_books"); +getstr ("filemask"); + +pageheader ("Files for EBook #$fk_books"); + +p ("Careful! If you change the Ebook number you link the file to a different Ebook."); +p ("Note: you cannot add files to the database. " . + "That is done automagically by a nightly cron job."); + +p ("Goto Edit Book Page — " . + "etext/${fk_books}\">Goto Bibrec Page"); + +function mk_options ($name, $options, $option) { + $ret = ""; + foreach ($options as $value => $opt) { + $selected = ($opt == $option) ? " selected=\"selected\"" : ""; + $ret .= "\n"; + } + return "\n"; +} + +$filetypes[null] = "unknown"; +$db->Exec ("select * from filetypes order by filetype"); +if ($db->FirstRow ()) { + do { + $filetypes[$db->Get ("pk")] = $db->Get ("filetype"); + } while ($db->NextRow ()); +} + +$compressions[null] = "unknown"; +$db->Exec ("select * from compressions order by compression"); +if ($db->FirstRow ()) { + do { + $compressions[$db->Get ("pk")] = $db->Get ("compression"); + } while ($db->NextRow ()); +} + +$encodings[null] = "unknown"; +$db->Exec ("select * from encodings order by pk"); +if ($db->FirstRow ()) { + do { + $encodings[$db->Get ("pk")] = $db->Get ("pk"); + } while ($db->NextRow ()); +} + +class HeadColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "", "narrow"); + } + function Data ($db) { + $filename = $db->get ("filename"); + if (preg_match ("/\.zip$/i", $filename)) + return "Dir"; + return "Head"; + } +} + +class CharsetColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "", "narrow"); + } + function Data ($db) { + $filename = $db->get ("filename"); + if (preg_match ("/\.zip$/i", $filename)) + return ""; + return "Guess"; + } +} + +class SizeColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Size", "pgdbfilessize"); + } + function Header () { + return "Size"; + } + function Data ($db) { + return "" . human_readable_size ($db->get ("filesize")) . ""; + } +} + +class FiletypeColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "File Type", "pgdbfilesfiletype"); + } + function Data ($db) { + global $filetypes; + return "" . mk_options ("fk_filetypes", $filetypes, $db->get ("filetype")) . ""; + } +} + +class CompressionColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Compression", "pgdbfilescompression"); + } + function Data ($db) { + global $compressions; + return "" . mk_options ("fk_compressions", $compressions, $db->get ("compression")) . ""; + } +} + +class EncodingColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Encoding", "pgdbfilesencoding"); + } + function Data ($db) { + global $encodings; + return "" . mk_options ("fk_encodings", $encodings, $db->get ("fk_encodings")) . ""; + } +} + +class ObsoletedColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Obs.", "pgdbfilesobsoleted"); + } + function Data ($db) { + $obs = $db->get ("obsoleted", SQLINT) ? " checked=\"checked\"" : ""; + $pk = $db->get ("pk", SQLINT); + return ""; + } +} + +form_open_get (); +echo ("Enter Perl RegExp: eg. /12345/"); +form_relay ("fk_books"); +form_submit ("Reload"); +form_close (); + +// Files for book +$prefix = "AddColumn ("", "", "narrow"); +$t->AddColumn ("$prefix=edit&fk_files=#pk#\">Edit", "", "narrow"); +$t->AddColumnObject (new HeadColumn ()); +$t->AddColumn ("Bug", "", "narrow"); +$t->AddColumn ("downloadbase/#filename#\">#filename#" . + "", + "Filename"); +$t->AddColumn ("" . + "", "EBook"); +$t->AddColumn ("", "Edition"); +$t->AddColumnObject (new ObsoletedColumn ()); +$t->AddColumnObject (new FiletypeColumn ()); +$t->AddColumnObject (new EncodingColumn ()); +$t->AddColumnObject (new CharsetColumn ()); +$t->AddColumnObject (new CompressionColumn ()); +$t->AddColumnObject (new SizeColumn ()); + +///////////////////////////////////////////////////////////////////////////////// +// Generate list of candidate files +// + +/*if (empty ($filemask)) { + if ($fk_books > 10000) { + $filemask = "/${fk_books}[.-]"; + } else { + $db->Exec ("select * from books where pk = $fk_books"); + $filemask = $db->Get ("filemask"); + if (!empty ($filemask)) { + $filemask = preg_replace ("/\./", "\\.", $filemask); + $filemask = preg_replace ("/x+/", ".*", $filemask); + $filemask = preg_replace ("/^[?]/", "[78]", $filemask); + } + } +}*/ + +$sql = "select files.pk as pk, fk_books, filename, edition, obsoleted, filetype, " . + "compression, fk_encodings, filesize " . + "from files left join filetypes on files.fk_filetypes = filetypes.pk " . + "left join compressions on files.fk_compressions = compressions.pk " . + "where " . (empty ($filemask) ? "" : "filename ~ '$filemask' or ") . + "(fk_books = $fk_books and diskstatus = 0) " . + "order by (fk_books = $fk_books) desc, obsoleted, " . + "filetype, fk_encodings, compression, filename;"; + +$db->exec ($sql); + +form_open ("files2"); +$t->limit = 100; +$t->PrintTable ($db, "Files Linked to Book $fk_books or Matching RegExp: $filemask", "pgdbfiles"); +form_relay ("fk_books"); +form_relay ("filemask"); +form_submit ("Update Checked File Entries"); +form_close (); + +p ("To be implemented: functions for viewing bottom n lines from file, check +for character encoding, diff files, look into zips. In my copious free time."); + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/files2.php b/catalog/admin/files2.php new file mode 100644 index 0000000..2d010f3 --- /dev/null +++ b/catalog/admin/files2.php @@ -0,0 +1,71 @@ +db (); +$db->logger = new logger (); + +getint ("fk_files"); +getint ("fk_books"); +getstr ("filemask"); + +getarray ("pks_update"); +getarray ("pks"); +getarray ("fk_books_a"); +getarray ("filenames"); +getarray ("editions"); +getarray ("obsoleteds"); +getarray ("fk_filetypes"); +getarray ("fk_compressions"); +getarray ("fk_encodings"); + +foreach ($pks as $pk) { + $fk_book = array_shift ($fk_books_a); + $filename = array_shift ($filenames); + $edition = array_shift ($editions); + $fk_filetype = array_shift ($fk_filetypes); + $fk_compression = array_shift ($fk_compressions); + $fk_encoding = array_shift ($fk_encodings); + + // p ("file: $pk $filename $fk_book $fk_filetype $fk_compression $fk_encoding"); + + if (!in_array ($pk, $pks_update)) + continue; + + $sql_pk = $db->f ($pk, SQLINT); + $sql_fk_books = $db->f ($fk_book, SQLINT); + $sql_edition = $db->f ($edition, SQLINT); + $sql_obsoleted = $db->f ($obsoleted, SQLINT); + $sql_fk_filetypes = $db->f ($fk_filetype, SQLCHAR); + $sql_fk_compressions = $db->f ($fk_compression, SQLCHAR); + $sql_fk_encodings = $db->f ($fk_encoding, SQLCHAR); + $sql_obsoleted = in_array ($pk, $obsoleteds) ? 1 : 0; + + $sql = "update files set " . + "fk_books = $sql_fk_books, " . + "edition = $sql_edition, " . + "obsoleted = $sql_obsoleted, " . + "fk_filetypes = $sql_fk_filetypes, " . + "fk_compressions = $sql_fk_compressions, " . + "fk_encodings = $sql_fk_encodings " . + "where pk = $sql_pk"; + + // p ($sql); + + if ($db->exec ($sql)) { + msg ("File $filename updated !"); + } else { + error_msg ("Could not update file $filename !"); + } +} + +p ("Back to Book Files"); + +pagefooter (); + +?> diff --git a/catalog/admin/files2.php~ b/catalog/admin/files2.php~ new file mode 100644 index 0000000..e1211af --- /dev/null +++ b/catalog/admin/files2.php~ @@ -0,0 +1,70 @@ +db (); +$db->logger = new logger (); + +getint ("fk_files"); +getint ("fk_books"); +getstr ("filemask"); + +getarray ("pks_update"); +getarray ("pks"); +getarray ("fk_books_a"); +getarray ("filenames"); +getarray ("editions"); +getarray ("obsoleteds"); +getarray ("fk_filetypes"); +getarray ("fk_compressions"); +getarray ("fk_encodings"); + +foreach ($pks as $pk) { + $fk_book = array_shift ($fk_books_a); + $filename = array_shift ($filenames); + $edition = array_shift ($editions); + $fk_filetype = array_shift ($fk_filetypes); + $fk_compression = array_shift ($fk_compressions); + $fk_encoding = array_shift ($fk_encodings); + + // p ("file: $pk $filename $fk_book $fk_filetype $fk_compression $fk_encoding"); + + if (!in_array ($pk, $pks_update)) + continue; + + $sql_pk = $db->f ($pk, SQLINT); + $sql_fk_books = $db->f ($fk_book, SQLINT); + $sql_edition = $db->f ($edition, SQLINT); + $sql_obsoleted = $db->f ($obsoleted, SQLINT); + $sql_fk_filetypes = $db->f ($fk_filetype, SQLCHAR); + $sql_fk_compressions = $db->f ($fk_compression, SQLCHAR); + $sql_fk_encodings = $db->f ($fk_encoding, SQLCHAR); + $sql_obsoleted = in_array ($pk, $obsoleteds) ? 1 : 0; + + $sql = "update files set " . + "fk_books = $sql_fk_books, " . + "edition = $sql_edition, " . + "obsoleted = $sql_obsoleted, " . + "fk_filetypes = $sql_fk_filetypes, " . + "fk_compressions = $sql_fk_compressions, " . + "fk_encodings = $sql_fk_encodings " . + "where pk = $sql_pk"; + + // p ($sql); + + if ($db->exec ($sql)) { + msg ("File $filename updated !"); + } else { + error_msg ("Could not update file $filename !"); + } +} + +p ("Back to Book Files"); + +pagefooter (); + +?> diff --git a/catalog/admin/fix-fileinfos.php b/catalog/admin/fix-fileinfos.php new file mode 100644 index 0000000..2dc08dc --- /dev/null +++ b/catalog/admin/fix-fileinfos.php @@ -0,0 +1,35 @@ +db (); + +set_time_limit (0); + +$cnt = 0; +$db->Exec ("select filename from files where diskstatus = 5 order by filename"); +if ($db->FirstRow ()) { + do { + $filename = $db->Get ("filename", SQLCHAR); + $infofile = "$config->privateroot/fileinfo/$filename.info"; + echo ("unlinking $infofile\n"); + if (unlink ($infofile)) + $cnt++; + } while ($db->NextRow ()); +} + +echo ("unlinked $cnt files.\n"); + +echo ("Done.\n"); + +?> diff --git a/catalog/admin/fix-fileinfos.php~ b/catalog/admin/fix-fileinfos.php~ new file mode 100644 index 0000000..f3aced7 --- /dev/null +++ b/catalog/admin/fix-fileinfos.php~ @@ -0,0 +1,34 @@ +db (); + +set_time_limit (0); + +$cnt = 0; +$db->Exec ("select filename from files where diskstatus = 5 order by filename"); +if ($db->FirstRow ()) { + do { + $filename = $db->Get ("filename", SQLCHAR); + $infofile = "$config->privateroot/fileinfo/$filename.info"; + echo ("unlinking $infofile\n"); + if (unlink ($infofile)) + $cnt++; + } while ($db->NextRow ()); +} + +echo ("unlinked $cnt files.\n"); + +echo ("Done.\n"); + +?> diff --git a/catalog/admin/fixcontents.php b/catalog/admin/fixcontents.php new file mode 100644 index 0000000..fad7407 --- /dev/null +++ b/catalog/admin/fixcontents.php @@ -0,0 +1,32 @@ +db (); +$db2 = $config->db (); + +$db->exec ("select * from attributes where fk_attriblist = 505 and text ~ '^Contents:' order by text"); + +if ($db->FirstRow ()) { + do { + $title = $db->get ("text", SQLCHAR); + $orig = $title; + $pk = $db->get ("pk", SQLINT); + $nonfiling = ""; + + $title = preg_replace ("/^Contents: /", "", $title); + + if ($title != $orig) { + $sql_title = $db-> f ($title, SQLCHAR); + echo ("update attributes set text = $sql_title where pk = $pk\n"); + $db2->exec ("update attributes set text = $sql_title where pk = $pk"); + } + + } while ($db->NextRow ()); +} + +?> diff --git a/catalog/admin/fixcontents.php~ b/catalog/admin/fixcontents.php~ new file mode 100644 index 0000000..f87aaab --- /dev/null +++ b/catalog/admin/fixcontents.php~ @@ -0,0 +1,31 @@ +db (); +$db2 = $config->db (); + +$db->exec ("select * from attributes where fk_attriblist = 505 and text ~ '^Contents:' order by text"); + +if ($db->FirstRow ()) { + do { + $title = $db->get ("text", SQLCHAR); + $orig = $title; + $pk = $db->get ("pk", SQLINT); + $nonfiling = ""; + + $title = preg_replace ("/^Contents: /", "", $title); + + if ($title != $orig) { + $sql_title = $db-> f ($title, SQLCHAR); + echo ("update attributes set text = $sql_title where pk = $pk\n"); + $db2->exec ("update attributes set text = $sql_title where pk = $pk"); + } + + } while ($db->NextRow ()); +} + +?> diff --git a/catalog/admin/fixentities.php b/catalog/admin/fixentities.php new file mode 100644 index 0000000..eddb9b8 --- /dev/null +++ b/catalog/admin/fixentities.php @@ -0,0 +1,95 @@ +db (); +$db2 = $config->db (); + +$trans = get_html_translation_table (HTML_ENTITIES); +$trans = array_flip ($trans); +array_walk ($trans, create_function ('&$v,$k', '$v = utf8_encode ($v);')); +$trans['—'] = chr (0xe2) . chr (0x80) . chr (0x94); +$trans['–'] = chr (0xe2) . chr (0x80) . chr (0x93); + + +$cnt = 0; + +$db->exec ("select * from titles order by title"); + +if ($db->FirstRow ()) { + do { + $title = $db->get ("title", SQLCHAR); + $orig = $title; + $pk = $db->get ("pk", SQLINT); + + $title = strtr ($title, $trans); + + if ($title != $orig) { + $sql_title = $db-> f ($title, SQLCHAR); + echo ("update titles set title = $sql_title where pk = $pk\n"); + $db2->exec ("update titles set title = $sql_title where pk = $pk"); + $cnt++; + } + + } while ($db->NextRow ()); +} + +echo ("$cnt title changes\n"); + + + +$cnt = 0; + +$db->exec ("select * from authors order by author"); + +if ($db->FirstRow ()) { + do { + $author = $db->get ("author", SQLCHAR); + $orig = $author; + $pk = $db->get ("pk", SQLINT); + + $author = strtr ($author, $trans); + + if ($author != $orig) { + $sql_author = $db-> f ($author, SQLCHAR); + echo ("update authors set author = $sql_author where pk = $pk\n"); + $db2->exec ("update authors set author = $sql_author where pk = $pk"); + $cnt++; + } + + } while ($db->NextRow ()); +} + +echo ("$cnt author changes\n"); + + + +$cnt = 0; + +$db->exec ("select * from aliases order by alias"); + +if ($db->FirstRow ()) { + do { + $alias = $db->get ("alias", SQLCHAR); + $orig = $alias; + $pk = $db->get ("pk", SQLINT); + + $alias = strtr ($alias, $trans); + + if ($alias != $orig) { + $sql_alias = $db-> f ($alias, SQLCHAR); + echo ("update aliases set alias = $sql_alias where pk = $pk\n"); + $db2->exec ("update aliases set alias = $sql_alias where pk = $pk"); + $cnt++; + } + + } while ($db->NextRow ()); +} + +echo ("$cnt alias changes\n"); + +?> diff --git a/catalog/admin/fixentities.php~ b/catalog/admin/fixentities.php~ new file mode 100644 index 0000000..04b9973 --- /dev/null +++ b/catalog/admin/fixentities.php~ @@ -0,0 +1,94 @@ +db (); +$db2 = $config->db (); + +$trans = get_html_translation_table (HTML_ENTITIES); +$trans = array_flip ($trans); +array_walk ($trans, create_function ('&$v,$k', '$v = utf8_encode ($v);')); +$trans['—'] = chr (0xe2) . chr (0x80) . chr (0x94); +$trans['–'] = chr (0xe2) . chr (0x80) . chr (0x93); + + +$cnt = 0; + +$db->exec ("select * from titles order by title"); + +if ($db->FirstRow ()) { + do { + $title = $db->get ("title", SQLCHAR); + $orig = $title; + $pk = $db->get ("pk", SQLINT); + + $title = strtr ($title, $trans); + + if ($title != $orig) { + $sql_title = $db-> f ($title, SQLCHAR); + echo ("update titles set title = $sql_title where pk = $pk\n"); + $db2->exec ("update titles set title = $sql_title where pk = $pk"); + $cnt++; + } + + } while ($db->NextRow ()); +} + +echo ("$cnt title changes\n"); + + + +$cnt = 0; + +$db->exec ("select * from authors order by author"); + +if ($db->FirstRow ()) { + do { + $author = $db->get ("author", SQLCHAR); + $orig = $author; + $pk = $db->get ("pk", SQLINT); + + $author = strtr ($author, $trans); + + if ($author != $orig) { + $sql_author = $db-> f ($author, SQLCHAR); + echo ("update authors set author = $sql_author where pk = $pk\n"); + $db2->exec ("update authors set author = $sql_author where pk = $pk"); + $cnt++; + } + + } while ($db->NextRow ()); +} + +echo ("$cnt author changes\n"); + + + +$cnt = 0; + +$db->exec ("select * from aliases order by alias"); + +if ($db->FirstRow ()) { + do { + $alias = $db->get ("alias", SQLCHAR); + $orig = $alias; + $pk = $db->get ("pk", SQLINT); + + $alias = strtr ($alias, $trans); + + if ($alias != $orig) { + $sql_alias = $db-> f ($alias, SQLCHAR); + echo ("update aliases set alias = $sql_alias where pk = $pk\n"); + $db2->exec ("update aliases set alias = $sql_alias where pk = $pk"); + $cnt++; + } + + } while ($db->NextRow ()); +} + +echo ("$cnt alias changes\n"); + +?> diff --git a/catalog/admin/fixorphans.php b/catalog/admin/fixorphans.php new file mode 100644 index 0000000..37a9958 --- /dev/null +++ b/catalog/admin/fixorphans.php @@ -0,0 +1,42 @@ +db (); +$db2 = $config->db (); + +function getno ($filename) { + $etext_number = null; + if (preg_match ("/^(?:\d\/)+(\d{2,5})/", $filename, $matches)) { + $etext_number = intval ($matches[1]); + // double-check this + $dir = etext2dir ($etext_number); + if (strncmp ("$filename/", $dir, strlen ($dir))) + $etext_number = null; + } elseif (preg_match ("/^([1-9])$/", $filename, $matches)) { + $etext_number = intval ($matches[1]); + } + return $etext_number; +} + +$db->exec ("select pk, filename from files where fk_books is null and diskstatus != 2"); +if ($db->FirstRow ()) { + do { + $pk = $db->get ("pk", SQLINT); + $filename = $db->get ("filename", SQLCHAR); + $no = getno ($filename); + if (!empty ($no)) { + echo ("$no $filename\n"); + $db2->exec ("update files set fk_books = $no where pk = $pk"); + } + } while ($db->Nextrow ()); +} + + +?> diff --git a/catalog/admin/fixorphans.php~ b/catalog/admin/fixorphans.php~ new file mode 100644 index 0000000..c60e11d --- /dev/null +++ b/catalog/admin/fixorphans.php~ @@ -0,0 +1,41 @@ +db (); +$db2 = $config->db (); + +function getno ($filename) { + $etext_number = null; + if (preg_match ("/^(?:\d\/)+(\d{2,5})/", $filename, $matches)) { + $etext_number = intval ($matches[1]); + // double-check this + $dir = etext2dir ($etext_number); + if (strncmp ("$filename/", $dir, strlen ($dir))) + $etext_number = null; + } elseif (preg_match ("/^([1-9])$/", $filename, $matches)) { + $etext_number = intval ($matches[1]); + } + return $etext_number; +} + +$db->exec ("select pk, filename from files where fk_books is null and diskstatus != 2"); +if ($db->FirstRow ()) { + do { + $pk = $db->get ("pk", SQLINT); + $filename = $db->get ("filename", SQLCHAR); + $no = getno ($filename); + if (!empty ($no)) { + echo ("$no $filename\n"); + $db2->exec ("update files set fk_books = $no where pk = $pk"); + } + } while ($db->Nextrow ()); +} + + +?> diff --git a/catalog/admin/fixtitles.php b/catalog/admin/fixtitles.php new file mode 100644 index 0000000..fbf17de --- /dev/null +++ b/catalog/admin/fixtitles.php @@ -0,0 +1,61 @@ +db (); +$db2 = $config->db (); + +$articles = array ("The", "A", "An", "La", "Le", "Der", "Die", "Das"); +$prepositions = array ("The", "A", "An", "In", "From", "To", "On", "Of", "Out", "For", + "Into", "At", "About", "And", "Or", "But", "With", "Under", "Over", "As"); + +foreach ($prepositions as $s) { + $search[] = " $s "; + $replace[] = strtolower (" $s "); +} + +$search[] = "--"; +$replace[] = "—"; +$search[] = "Vol."; +$replace[] = "Volume"; +$search[] = "vol."; +$replace[] = "Volume"; + + +$db->exec ("select * from titles order by title"); + +if ($db->FirstRow ()) { + do { + $title = $db->get ("title", SQLCHAR); + $orig = $title; + $pk = $db->get ("pk", SQLINT); + $nonfiling = ""; + + if (preg_match ("/Reserved:/i", $title)) + continue; + + foreach ($articles as $article) { + if (preg_match ("/, $article\$/", $title)) { + $title = preg_replace ("/, $article\$/", "", $title); + $title = "$article $title"; + $nonfiling = ", nonfiling = " . strlen ("$article "); + break; + } + } + + $title = str_replace ($search, $replace, $title); + + if ($title != $orig) { + $sql_title = $db-> f ($title, SQLCHAR); + echo ("update titles set title = $sql_title$nonfiling where pk = $pk\n"); + $db2->exec ("update titles set title = $sql_title$nonfiling where pk = $pk"); + } + + } while ($db->NextRow ()); +} + +?> diff --git a/catalog/admin/fixtitles.php~ b/catalog/admin/fixtitles.php~ new file mode 100644 index 0000000..5b004a0 --- /dev/null +++ b/catalog/admin/fixtitles.php~ @@ -0,0 +1,60 @@ +db (); +$db2 = $config->db (); + +$articles = array ("The", "A", "An", "La", "Le", "Der", "Die", "Das"); +$prepositions = array ("The", "A", "An", "In", "From", "To", "On", "Of", "Out", "For", + "Into", "At", "About", "And", "Or", "But", "With", "Under", "Over", "As"); + +foreach ($prepositions as $s) { + $search[] = " $s "; + $replace[] = strtolower (" $s "); +} + +$search[] = "--"; +$replace[] = "—"; +$search[] = "Vol."; +$replace[] = "Volume"; +$search[] = "vol."; +$replace[] = "Volume"; + + +$db->exec ("select * from titles order by title"); + +if ($db->FirstRow ()) { + do { + $title = $db->get ("title", SQLCHAR); + $orig = $title; + $pk = $db->get ("pk", SQLINT); + $nonfiling = ""; + + if (preg_match ("/Reserved:/i", $title)) + continue; + + foreach ($articles as $article) { + if (preg_match ("/, $article\$/", $title)) { + $title = preg_replace ("/, $article\$/", "", $title); + $title = "$article $title"; + $nonfiling = ", nonfiling = " . strlen ("$article "); + break; + } + } + + $title = str_replace ($search, $replace, $title); + + if ($title != $orig) { + $sql_title = $db-> f ($title, SQLCHAR); + echo ("update titles set title = $sql_title$nonfiling where pk = $pk\n"); + $db2->exec ("update titles set title = $sql_title$nonfiling where pk = $pk"); + } + + } while ($db->NextRow ()); +} + +?> diff --git a/catalog/admin/fixurls.php b/catalog/admin/fixurls.php new file mode 100644 index 0000000..70e506e --- /dev/null +++ b/catalog/admin/fixurls.php @@ -0,0 +1,51 @@ +db (); +$db2 = $config->db (); + +$cnt = 0; + +$db->exec ("select * from author_urls order by url"); + +if ($db->FirstRow ()) { + do { + $url = $db->get ("url", SQLCHAR); + $orig = $url; + $pk = $db->get ("pk", SQLINT); + + $url = rawurldecode ($url); + if ($url == $orig) { + continue; + } + + // echo ("$orig\n"); + + if (utf8_encode (utf8_decode ($url)) != $url) { + // not an utf-8 string + if (($url = iconv ("ISO-8859-1", "UTF-8", $url)) === FALSE) { + // nor an iso-8859-1 one ??? + // punt on this one + continue; + } + } + + // echo ("$url\n"); + + if ($url != $orig) { + $sql_url = $db-> f ($url, SQLCHAR); + echo ("update author_urls set url = $sql_url where pk = $pk\n"); + $db2->exec ("update author_urls set url = $sql_url where pk = $pk;"); + $cnt++; + } + + } while ($db->NextRow ()); +} + +echo ("$cnt url changes\n"); +?> diff --git a/catalog/admin/fixurls.php~ b/catalog/admin/fixurls.php~ new file mode 100644 index 0000000..773c00d --- /dev/null +++ b/catalog/admin/fixurls.php~ @@ -0,0 +1,50 @@ +db (); +$db2 = $config->db (); + +$cnt = 0; + +$db->exec ("select * from author_urls order by url"); + +if ($db->FirstRow ()) { + do { + $url = $db->get ("url", SQLCHAR); + $orig = $url; + $pk = $db->get ("pk", SQLINT); + + $url = rawurldecode ($url); + if ($url == $orig) { + continue; + } + + // echo ("$orig\n"); + + if (utf8_encode (utf8_decode ($url)) != $url) { + // not an utf-8 string + if (($url = iconv ("ISO-8859-1", "UTF-8", $url)) === FALSE) { + // nor an iso-8859-1 one ??? + // punt on this one + continue; + } + } + + // echo ("$url\n"); + + if ($url != $orig) { + $sql_url = $db-> f ($url, SQLCHAR); + echo ("update author_urls set url = $sql_url where pk = $pk\n"); + $db2->exec ("update author_urls set url = $sql_url where pk = $pk;"); + $cnt++; + } + + } while ($db->NextRow ()); +} + +echo ("$cnt url changes\n"); +?> diff --git a/catalog/admin/gutindex-parser.php b/catalog/admin/gutindex-parser.php new file mode 100644 index 0000000..25dd90e --- /dev/null +++ b/catalog/admin/gutindex-parser.php @@ -0,0 +1,82 @@ +documentroot/dirs/GUTINDEX.ALL.iso-8859-1.txt"; + +$fp = fopen ($gutindex, "r"); +if (!$fp) { + die ("cannot open $gutindex"); +} + +$db = $config->db (); + +$pks = array (); +$gutindex = array (); + +$db->exec ("select * from books"); +if ($db->FirstRow ()) { + do { + $pk = $db->get ("pk", SQLINT); + $pks[$pk] = 1; + } while ($db->NextRow ()); +} + +$mode = 0; +$pk = 0; +$buffer = ""; + +while (!feof ($fp)) { + $line = fgets ($fp); + $tline = trim ($line); + + switch ($mode) { + case 0: + if (preg_match ("/^~ ~ ~ ~/", $tline, $matches)) { + $mode = 1; + } + break; + case 1: + if ($tline == "<==End of GUTINDEX.ALL==>") { + $mode = 0; + break; + } + // fall thru + case 2: + if (preg_match ("/(\d+)[-BC]?$/", $tline, $matches)) { + if (!preg_match ("/GUTINDEX/", $tline)) { + $gutindex[$pk] = $buffer; + $buffer = utf8_encode ($line); + $mode = 2; + $pk = intval ($matches [1]); + break; + } + } + if (empty ($tline) || preg_match ("/\*$/", $tline)) { + $gutindex[$pk] = $buffer; + $buffer = ""; + $mode = 1; + $pk = 0; + break; + } + $buffer .= utf8_encode ($line); + break; + } +} + +fclose ($fp); + +foreach ($gutindex as $pk => $book) { + if (isset ($pks[$pk])) { + $sql_book = $db->f ($book, SQLCHAR); + $db->exec ("update books set gutindex = $sql_book where pk = $pk"); + $db->exec ("commit"); + // echo ("Updated #$pk\n"); + } +} + +?> diff --git a/catalog/admin/gutindex-parser.php~ b/catalog/admin/gutindex-parser.php~ new file mode 100644 index 0000000..d0e0433 --- /dev/null +++ b/catalog/admin/gutindex-parser.php~ @@ -0,0 +1,81 @@ +documentroot/dirs/GUTINDEX.ALL.iso-8859-1.txt"; + +$fp = fopen ($gutindex, "r"); +if (!$fp) { + die ("cannot open $gutindex"); +} + +$db = $config->db (); + +$pks = array (); +$gutindex = array (); + +$db->exec ("select * from books"); +if ($db->FirstRow ()) { + do { + $pk = $db->get ("pk", SQLINT); + $pks[$pk] = 1; + } while ($db->NextRow ()); +} + +$mode = 0; +$pk = 0; +$buffer = ""; + +while (!feof ($fp)) { + $line = fgets ($fp); + $tline = trim ($line); + + switch ($mode) { + case 0: + if (preg_match ("/^~ ~ ~ ~/", $tline, $matches)) { + $mode = 1; + } + break; + case 1: + if ($tline == "<==End of GUTINDEX.ALL==>") { + $mode = 0; + break; + } + // fall thru + case 2: + if (preg_match ("/(\d+)[-BC]?$/", $tline, $matches)) { + if (!preg_match ("/GUTINDEX/", $tline)) { + $gutindex[$pk] = $buffer; + $buffer = utf8_encode ($line); + $mode = 2; + $pk = intval ($matches [1]); + break; + } + } + if (empty ($tline) || preg_match ("/\*$/", $tline)) { + $gutindex[$pk] = $buffer; + $buffer = ""; + $mode = 1; + $pk = 0; + break; + } + $buffer .= utf8_encode ($line); + break; + } +} + +fclose ($fp); + +foreach ($gutindex as $pk => $book) { + if (isset ($pks[$pk])) { + $sql_book = $db->f ($book, SQLCHAR); + $db->exec ("update books set gutindex = $sql_book where pk = $pk"); + $db->exec ("commit"); + // echo ("Updated #$pk\n"); + } +} + +?> \ No newline at end of file diff --git a/catalog/admin/head.php b/catalog/admin/head.php new file mode 100644 index 0000000..3b690b5 --- /dev/null +++ b/catalog/admin/head.php @@ -0,0 +1,29 @@ + 0)) { + $buffer = fgets ($hd, 4096); + echo ($buffer); + --$lines; +} +fclose ($hd); + +?> diff --git a/catalog/admin/head.php~ b/catalog/admin/head.php~ new file mode 100644 index 0000000..738b51e --- /dev/null +++ b/catalog/admin/head.php~ @@ -0,0 +1,27 @@ + 0)) { + $buffer = fgets ($hd, 4096); + echo ($buffer); + --$lines; +} +fclose ($hd); + +?> diff --git a/catalog/admin/index.php b/catalog/admin/index.php new file mode 100644 index 0000000..5487662 --- /dev/null +++ b/catalog/admin/index.php @@ -0,0 +1,139 @@ + + +

Read This First

+ +

Entities and relations

+ +

In this catalog you will find 2 different recurring concepts:

+ + + +

Don't confuse database link (relation) with HTML-link (underlined +text to click.)

+ +

Book, Author, Subject, Language and LoC Class are entities.

+ +

Book-Author, Book-Subject, Book-Language and Book-LoC Class are +relations.

+ +

You can add, edit and +delete entities. Add an author, add a book. You can +create and remove links between existing entities (link +and unlink entities). Link an author to a book. +Remember: to link you have to create the entities first. Of course, if +you find that the entity already exists in the catalog, you should not +create it again.

+ +

The advantage of the entity and link concept is that you have to enter data +only once. Every author exists only once in the database. You have to enter +the date of birth and of death only once. You have to enter the pseudonyms +and different orthografies of the name only once. If you find an error, you +have to fix it only once.

+ +

To add a new book:

+ +
    +
  1. Search for the author. If you don't find her, add her.
  2. +
  3. Enter the book data.
  4. +
  5. Link the author to the book.
  6. +
+ +

HTML-Links and Buttons

+ +

Clicking on a HTML-link will never alter any data.

+ +

Clicking on a button with: add, edit, delete, link or unlink in the +caption will alter data. (There are some other buttons though that don't +alter data.)

+ +

Starting points

+ +

Reports / Statistics

+ +

MARC Attribute usage

+ +

List all the MARC attributes/tags/codes currently in the system, + and how many records use them; and see the usage.

+ +

Books lacking a Subject and/or a LoCC

+ +

List all the books which do not have any Subjects and/or LoCCs attached to them, + sorted by Etext#, i.e. least recent first.

+ +

Statistics

+ +

Various statistics, mainly focused on authors.

+ +

Authors with no books

+ +

A list of author entries that have no books attached to them, which usually means + they should be deleted.

+ +

Duplicate MARC attributes

+ +

MARC attributes whose values are not unique.

+ +

User Tasks

+ +

Authors

+ +

Manage authors, author aliases and interesting URLs for author.

+ +

Books

+ +

Manage books, book-titles, book-authors, book-subjects, book-languages +and book-LoC classes.

+ +

Batch-Edit Titles

+ +

Select a batch of titles by regular expression and +edit them all in one place.

+ +

Subjects

+ +

Manage subjects.

+ +

Categories

+ +

Manage categories.

+ +

LoC Classes

+ +

Manage LoC Classes.

+ +

Languages

+ +

Manage Languages. You will seldom need this, as most languages are +already entered.

+ +

Change Password

+ +

Change your password. You'll probably have to login again.

+ +

Administrator Tasks

+ +

Requires Administrator rights.

+ +

Users

+ +

Manage users. Add, remove, reset password etc.

+ +

Mirrors

+ +

Manage mirrors.

+ + + diff --git a/catalog/admin/index.php~ b/catalog/admin/index.php~ new file mode 100644 index 0000000..fbf1307 --- /dev/null +++ b/catalog/admin/index.php~ @@ -0,0 +1,137 @@ + + +

Read This First

+ +

Entities and relations

+ +

In this catalog you will find 2 different recurring concepts:

+ + + +

Don't confuse database link (relation) with HTML-link (underlined +text to click.)

+ +

Book, Author, Subject, Language and LoC Class are entities.

+ +

Book-Author, Book-Subject, Book-Language and Book-LoC Class are +relations.

+ +

You can add, edit and +delete entities. Add an author, add a book. You can +create and remove links between existing entities (link +and unlink entities). Link an author to a book. +Remember: to link you have to create the entities first. Of course, if +you find that the entity already exists in the catalog, you should not +create it again.

+ +

The advantage of the entity and link concept is that you have to enter data +only once. Every author exists only once in the database. You have to enter +the date of birth and of death only once. You have to enter the pseudonyms +and different orthografies of the name only once. If you find an error, you +have to fix it only once.

+ +

To add a new book:

+ +
    +
  1. Search for the author. If you don't find her, add her.
  2. +
  3. Enter the book data.
  4. +
  5. Link the author to the book.
  6. +
+ +

HTML-Links and Buttons

+ +

Clicking on a HTML-link will never alter any data.

+ +

Clicking on a button with: add, edit, delete, link or unlink in the +caption will alter data. (There are some other buttons though that don't +alter data.)

+ +

Starting points

+ +

Reports / Statistics

+ +

MARC Attribute usage

+ +

List all the MARC attributes/tags/codes currently in the system, + and how many records use them; and see the usage.

+ +

Books lacking a Subject and/or a LoCC

+ +

List all the books which do not have any Subjects and/or LoCCs attached to them, + sorted by Etext#, i.e. least recent first.

+ +

Statistics

+ +

Various statistics, mainly focused on authors.

+ +

Authors with no books

+ +

A list of author entries that have no books attached to them, which usually means + they should be deleted.

+ +

Duplicate MARC attributes

+ +

MARC attributes whose values are not unique.

+ +

User Tasks

+ +

Authors

+ +

Manage authors, author aliases and interesting URLs for author.

+ +

Books

+ +

Manage books, book-titles, book-authors, book-subjects, book-languages +and book-LoC classes.

+ +

Batch-Edit Titles

+ +

Select a batch of titles by regular expression and +edit them all in one place.

+ +

Subjects

+ +

Manage subjects.

+ +

Categories

+ +

Manage categories.

+ +

LoC Classes

+ +

Manage LoC Classes.

+ +

Languages

+ +

Manage Languages. You will seldom need this, as most languages are +already entered.

+ +

Change Password

+ +

Change your password. You'll probably have to login again.

+ +

Administrator Tasks

+ +

Requires Administrator rights.

+ +

Users

+ +

Manage users. Add, remove, reset password etc.

+ +

Mirrors

+ +

Manage mirrors.

+ + + diff --git a/catalog/admin/ip-activity.php b/catalog/admin/ip-activity.php new file mode 100644 index 0000000..3289c1a --- /dev/null +++ b/catalog/admin/ip-activity.php @@ -0,0 +1,128 @@ + $cnt) { + p ("$ip => $cnt"); +} + +/* + + +function fixnetwork ($ip) { + if (($pos = strpos ($ip, "/")) !== false) { + $ip = substr ($ip, 0, $pos); + $ip = long2ip (ip2long ($ip) + 1); + } + return $ip; +} + +class CalcFieldHost { + function f ($db) { + return @gethostbyaddr (fixnetwork ($db->get ("ip", SQLCHAR))); + } +} + +class CalcFieldRBL { + function __construct ($list) { + $this->list = $list; + } + function f ($db) { + $ip = fixnetwork ($db->get ("ip", SQLCHAR)); + $reverse_ip = join (".", array_reverse (explode (".", $ip))); + $host = gethostbyname ("$reverse_ip.$this->list"); + // return $host; // debug + return strncmp ($host, "127.", 4) ? "" : "Yes"; + } +} + +class RobotHitTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("date", "Date"); + $this->AddSimpleColumn ("ip", "IP"); + $this->AddSimpleColumn ("c_host", "Host"); + $this->AddSimpleColumn ("hits", "Hits"); + $this->AddSimpleColumn ("restricted", "Restricted"); + $this->AddSimpleColumn ("c_isdialup", "Dialup"); + $this->AddSimpleColumn ("c_spam", "Spam"); + $this->AddSimpleColumn ("c_spews", "SPEWS"); + } +} + +class RobotJailTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("firstseen", "First Sighted"); + $this->AddSimpleColumn ("lastseen", "Last Seen"); + $this->AddSimpleColumn ("ip", "IP"); + $this->AddSimpleColumn ("c_host", "Host"); + $this->AddSimpleColumn ("hits", "Hits"); + $this->AddSimpleColumn ("restricted", "Restricted"); + $this->AddSimpleColumn ("charge", "Charge"); + $this->AddSimpleColumn ("c_isdialup", "Dialup"); + $this->AddSimpleColumn ("c_spam", "Spam"); + $this->AddSimpleColumn ("c_spews", "SPEWS"); + $this->AddSimpleColumn ("ua", "User-Agent"); + } +} + +$db = $config->db (); + +$db->exec ("select * from robots.stat"); +$lastcron = $db->get ("lastcron", SQLCHAR); +p ("Last Cron Run: $lastcron"); + +// Jailed + +$db->exec (" +select * from robots.jail order by firstseen; +"); + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_isdialup"] = new CalcFieldRBL ("dul.dnsbl.sorbs.net"); +$db->calcfields ["c_spam"] = new CalcFieldRBL ("spam.dnsbl.sorbs.net"); +$db->calcfields ["c_spews"] = new CalcFieldRBL ("l2.spews.dnsbl.sorbs.net"); + +$table = new RobotJailTable (); +$table->PrintTable ($db, "Currently Jailed Robots"); +flush (); + +// Recent + +$db->exec (" +select date, ip, hits, restricted from robots.hit_totals +union +select current_date, ip, count (ip), sum (restricted) from robots.hits +group by ip having count (ip) > 1000 +order by date desc, ip; +"); + + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_isdialup"] = new CalcFieldRBL ("dul.dnsbl.sorbs.net"); +$db->calcfields ["c_spam"] = new CalcFieldRBL ("spam.dnsbl.sorbs.net"); +$db->calcfields ["c_spews"] = new CalcFieldRBL ("l2.spews.dnsbl.sorbs.net"); + +$table = new RobotHitTable (); +$table->PrintTable ($db, "Recently Active Robots"); +flush (); +*/ + +pagefooter (); + +?> diff --git a/catalog/admin/ip-activity.php~ b/catalog/admin/ip-activity.php~ new file mode 100644 index 0000000..c1d9c6d --- /dev/null +++ b/catalog/admin/ip-activity.php~ @@ -0,0 +1,127 @@ + $cnt) { + p ("$ip => $cnt"); +} + +/* + + +function fixnetwork ($ip) { + if (($pos = strpos ($ip, "/")) !== false) { + $ip = substr ($ip, 0, $pos); + $ip = long2ip (ip2long ($ip) + 1); + } + return $ip; +} + +class CalcFieldHost { + function f ($db) { + return @gethostbyaddr (fixnetwork ($db->get ("ip", SQLCHAR))); + } +} + +class CalcFieldRBL { + function __construct ($list) { + $this->list = $list; + } + function f ($db) { + $ip = fixnetwork ($db->get ("ip", SQLCHAR)); + $reverse_ip = join (".", array_reverse (explode (".", $ip))); + $host = gethostbyname ("$reverse_ip.$this->list"); + // return $host; // debug + return strncmp ($host, "127.", 4) ? "" : "Yes"; + } +} + +class RobotHitTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("date", "Date"); + $this->AddSimpleColumn ("ip", "IP"); + $this->AddSimpleColumn ("c_host", "Host"); + $this->AddSimpleColumn ("hits", "Hits"); + $this->AddSimpleColumn ("restricted", "Restricted"); + $this->AddSimpleColumn ("c_isdialup", "Dialup"); + $this->AddSimpleColumn ("c_spam", "Spam"); + $this->AddSimpleColumn ("c_spews", "SPEWS"); + } +} + +class RobotJailTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("firstseen", "First Sighted"); + $this->AddSimpleColumn ("lastseen", "Last Seen"); + $this->AddSimpleColumn ("ip", "IP"); + $this->AddSimpleColumn ("c_host", "Host"); + $this->AddSimpleColumn ("hits", "Hits"); + $this->AddSimpleColumn ("restricted", "Restricted"); + $this->AddSimpleColumn ("charge", "Charge"); + $this->AddSimpleColumn ("c_isdialup", "Dialup"); + $this->AddSimpleColumn ("c_spam", "Spam"); + $this->AddSimpleColumn ("c_spews", "SPEWS"); + $this->AddSimpleColumn ("ua", "User-Agent"); + } +} + +$db = $config->db (); + +$db->exec ("select * from robots.stat"); +$lastcron = $db->get ("lastcron", SQLCHAR); +p ("Last Cron Run: $lastcron"); + +// Jailed + +$db->exec (" +select * from robots.jail order by firstseen; +"); + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_isdialup"] = new CalcFieldRBL ("dul.dnsbl.sorbs.net"); +$db->calcfields ["c_spam"] = new CalcFieldRBL ("spam.dnsbl.sorbs.net"); +$db->calcfields ["c_spews"] = new CalcFieldRBL ("l2.spews.dnsbl.sorbs.net"); + +$table = new RobotJailTable (); +$table->PrintTable ($db, "Currently Jailed Robots"); +flush (); + +// Recent + +$db->exec (" +select date, ip, hits, restricted from robots.hit_totals +union +select current_date, ip, count (ip), sum (restricted) from robots.hits +group by ip having count (ip) > 1000 +order by date desc, ip; +"); + + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_isdialup"] = new CalcFieldRBL ("dul.dnsbl.sorbs.net"); +$db->calcfields ["c_spam"] = new CalcFieldRBL ("spam.dnsbl.sorbs.net"); +$db->calcfields ["c_spews"] = new CalcFieldRBL ("l2.spews.dnsbl.sorbs.net"); + +$table = new RobotHitTable (); +$table->PrintTable ($db, "Recently Active Robots"); +flush (); +*/ + +pagefooter (); + +?> diff --git a/catalog/admin/lang.php b/catalog/admin/lang.php new file mode 100644 index 0000000..cf96ced --- /dev/null +++ b/catalog/admin/lang.php @@ -0,0 +1,106 @@ +AddColumn ("#pk#", + "Etext Nr.", "right", "1*"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddSimpleColumn ("title", "Title"); + $this->limit = 25; + $this->relay = array ("fk_langs", "mode", "filter"); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getstr ("fk_langs"); +getstr ("filter"); + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_langs " . + "where fk_langs = '$fk_langs'"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + $f->SubCaption ("Warning: There are $cnt books related to this language. "); + } + $f->SubCaption ("You are about to delete this language."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("fk_langs", "pk", "Id", SQLCHAR, 10, 10, true); + $f->Text ("lang", "lang", "Language", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from langs where pk = '$fk_langs'"); +} +$f->Hidden ("fk_langs"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into langs " . $sql)) { + msg ("Language added !"); + } else { + error_msg ("Could not add language!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update langs set " . $sql . "where pk = '$fk_langs'")) { + msg ("Language modified !"); + } else { + error_msg ("Could not modify language !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_books_langs where fk_langs = '$fk_langs'"); + if ($db->Exec ("delete from langs where pk = '$fk_langs'")) { + msg ("Language deleted !"); + } else { + error_msg ("Could not delete language !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + echo ("

" . + "Back to Lang

\n\n"); + } +} else { + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + $table = new ListBooksTable (); + $db->exec ("select books.pk as pk, title, author " . + "from books, mn_books_langs, titles, mn_books_authors, authors " . + "where books.pk = mn_books_langs.fk_books " . + "and books.pk = mn_books_authors.fk_books " . + "and authors.pk = mn_books_authors.fk_authors " . + "and books.pk = titles.fk_books " . + "and mn_books_langs.fk_langs = '$fk_langs' order by author, title " . + $table->MkOffset ()); + $table->PrintTable ($db, "Books for Language"); + } +} + +echo ("

" . + "Back to Language List

\n\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/lang.php~ b/catalog/admin/lang.php~ new file mode 100644 index 0000000..c149848 --- /dev/null +++ b/catalog/admin/lang.php~ @@ -0,0 +1,105 @@ +AddColumn ("#pk#", + "Etext Nr.", "right", "1*"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddSimpleColumn ("title", "Title"); + $this->limit = 25; + $this->relay = array ("fk_langs", "mode", "filter"); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getstr ("fk_langs"); +getstr ("filter"); + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_langs " . + "where fk_langs = '$fk_langs'"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + $f->SubCaption ("Warning: There are $cnt books related to this language. "); + } + $f->SubCaption ("You are about to delete this language."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("fk_langs", "pk", "Id", SQLCHAR, 10, 10, true); + $f->Text ("lang", "lang", "Language", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from langs where pk = '$fk_langs'"); +} +$f->Hidden ("fk_langs"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into langs " . $sql)) { + msg ("Language added !"); + } else { + error_msg ("Could not add language!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update langs set " . $sql . "where pk = '$fk_langs'")) { + msg ("Language modified !"); + } else { + error_msg ("Could not modify language !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_books_langs where fk_langs = '$fk_langs'"); + if ($db->Exec ("delete from langs where pk = '$fk_langs'")) { + msg ("Language deleted !"); + } else { + error_msg ("Could not delete language !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + echo ("

" . + "Back to Lang

\n\n"); + } +} else { + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + $table = new ListBooksTable (); + $db->exec ("select books.pk as pk, title, author " . + "from books, mn_books_langs, titles, mn_books_authors, authors " . + "where books.pk = mn_books_langs.fk_books " . + "and books.pk = mn_books_authors.fk_books " . + "and authors.pk = mn_books_authors.fk_authors " . + "and books.pk = titles.fk_books " . + "and mn_books_langs.fk_langs = '$fk_langs' order by author, title " . + $table->MkOffset ()); + $table->PrintTable ($db, "Books for Language"); + } +} + +echo ("

" . + "Back to Language List

\n\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/langs_list.php b/catalog/admin/langs_list.php new file mode 100644 index 0000000..49bb2a7 --- /dev/null +++ b/catalog/admin/langs_list.php @@ -0,0 +1,48 @@ +AddColumn ("$prefix=edit&fk_langs=#pk#\">Edit", + "$prefix=add\">Add", "left", "1%"); + $this->AddColumn ("$prefix=delete&fk_langs=#pk#\">Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("pk", "Id", "left", "1%"); + $this->AddSimpleColumn ("lang", "Language"); + $this->AddSimpleColumn ("cnt", "# of books"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the language (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. *ish) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select pk, lang, (select count(fk_books) from mn_books_langs where fk_langs=pk) as cnt from langs where lang like '$filt%' order by cnt, lang;"); + $table = new ListLangsTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/langs_list.php~ b/catalog/admin/langs_list.php~ new file mode 100644 index 0000000..3168cc7 --- /dev/null +++ b/catalog/admin/langs_list.php~ @@ -0,0 +1,47 @@ +AddColumn ("$prefix=edit&fk_langs=#pk#\">Edit", + "$prefix=add\">Add", "left", "1%"); + $this->AddColumn ("$prefix=delete&fk_langs=#pk#\">Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("pk", "Id", "left", "1%"); + $this->AddSimpleColumn ("lang", "Language"); + $this->AddSimpleColumn ("cnt", "# of books"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the language (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. *ish) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select pk, lang, (select count(fk_books) from mn_books_langs where fk_langs=pk) as cnt from langs where lang like '$filt%' order by cnt, lang;"); + $table = new ListLangsTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/locc.php b/catalog/admin/locc.php new file mode 100644 index 0000000..ea34326 --- /dev/null +++ b/catalog/admin/locc.php @@ -0,0 +1,105 @@ +AddColumn ("#pk#", + "Etext Nr.", "right", "1*"); + $this->AddSimpleColumn ("title", "Title"); + $this->limit = 25; + $this->relay = array ("fk_loccs", "mode", "filter"); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getstr ("fk_loccs"); +getstr ("filter"); + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_loccs " . + "where fk_loccs = '$fk_loccs'"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + $f->SubCaption ("Warning: There are $cnt books related to this LoC class. "); + } + $f->SubCaption ("You are about to delete this LoC class."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("fk_loccs", "pk", "Id", SQLCHAR, 10, 10, true); + $f->Text ("locc", "locc", "LoC Class", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from loccs where pk = '$fk_loccs'"); +} +$f->Hidden ("fk_loccs"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into loccs " . $sql)) { + msg ("LoC class added !"); + } else { + error_msg ("Could not add LoC class!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update loccs set " . $sql . "where pk = '$fk_loccs'")) { + msg ("LoC class modified !"); + } else { + error_msg ("Could not modify LoC class !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_books_loccs where fk_loccs = '$fk_loccs'"); + if ($db->Exec ("delete from loccs where pk = '$fk_loccs'")) { + msg ("LoC class deleted !"); + } else { + error_msg ("Could not delete LoC class !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + echo ("

" . + "Back to Locc

\n\n"); + } +} else { + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + $table = new ListBooksTable (); + $db->exec ("select books.pk as pk, title, author " . + "from books, mn_books_loccs, titles, mn_books_authors, authors " . + "where books.pk = mn_books_loccs.fk_books " . + "and books.pk = mn_books_authors.fk_books " . + "and authors.pk = mn_books_authors.fk_authors " . + "and books.pk = titles.fk_books " . + "and mn_books_loccs.fk_loccs = '$fk_loccs' order by author, title " . + $table->MkOffset ()); + $table->PrintTable ($db, "Books for LoC Class"); + } +} + +echo ("

" . + "Back to LoC Class List

\n\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/locc.php~ b/catalog/admin/locc.php~ new file mode 100644 index 0000000..1411c6a --- /dev/null +++ b/catalog/admin/locc.php~ @@ -0,0 +1,104 @@ +AddColumn ("#pk#", + "Etext Nr.", "right", "1*"); + $this->AddSimpleColumn ("title", "Title"); + $this->limit = 25; + $this->relay = array ("fk_loccs", "mode", "filter"); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getstr ("fk_loccs"); +getstr ("filter"); + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_loccs " . + "where fk_loccs = '$fk_loccs'"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + $f->SubCaption ("Warning: There are $cnt books related to this LoC class. "); + } + $f->SubCaption ("You are about to delete this LoC class."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("fk_loccs", "pk", "Id", SQLCHAR, 10, 10, true); + $f->Text ("locc", "locc", "LoC Class", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from loccs where pk = '$fk_loccs'"); +} +$f->Hidden ("fk_loccs"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into loccs " . $sql)) { + msg ("LoC class added !"); + } else { + error_msg ("Could not add LoC class!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update loccs set " . $sql . "where pk = '$fk_loccs'")) { + msg ("LoC class modified !"); + } else { + error_msg ("Could not modify LoC class !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_books_loccs where fk_loccs = '$fk_loccs'"); + if ($db->Exec ("delete from loccs where pk = '$fk_loccs'")) { + msg ("LoC class deleted !"); + } else { + error_msg ("Could not delete LoC class !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + echo ("

" . + "Back to Locc

\n\n"); + } +} else { + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + $table = new ListBooksTable (); + $db->exec ("select books.pk as pk, title, author " . + "from books, mn_books_loccs, titles, mn_books_authors, authors " . + "where books.pk = mn_books_loccs.fk_books " . + "and books.pk = mn_books_authors.fk_books " . + "and authors.pk = mn_books_authors.fk_authors " . + "and books.pk = titles.fk_books " . + "and mn_books_loccs.fk_loccs = '$fk_loccs' order by author, title " . + $table->MkOffset ()); + $table->PrintTable ($db, "Books for LoC Class"); + } +} + +echo ("

" . + "Back to LoC Class List

\n\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/loccs_list.php b/catalog/admin/loccs_list.php new file mode 100644 index 0000000..78c3f9e --- /dev/null +++ b/catalog/admin/loccs_list.php @@ -0,0 +1,47 @@ +AddColumn ("$prefix=edit&fk_loccs=#pk#\">Edit", + "$prefix=add\">Add", "left", "1%"); + $this->AddColumn ("$prefix=delete&fk_loccs=#pk#\">Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("pk", "Id", "left", "1%"); + $this->AddSimpleColumn ("locc", "LoC Class"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the LoC Class (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. *United*) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from loccs where locc like '$filt%' order by locc;"); + $table = new ListLoccsTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/loccs_list.php~ b/catalog/admin/loccs_list.php~ new file mode 100644 index 0000000..3cd4ea8 --- /dev/null +++ b/catalog/admin/loccs_list.php~ @@ -0,0 +1,46 @@ +AddColumn ("$prefix=edit&fk_loccs=#pk#\">Edit", + "$prefix=add\">Add", "left", "1%"); + $this->AddColumn ("$prefix=delete&fk_loccs=#pk#\">Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("pk", "Id", "left", "1%"); + $this->AddSimpleColumn ("locc", "LoC Class"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the LoC Class (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. *United*) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from loccs where locc like '$filt%' order by locc;"); + $table = new ListLoccsTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/ls.php b/catalog/admin/ls.php new file mode 100644 index 0000000..09c4195 --- /dev/null +++ b/catalog/admin/ls.php @@ -0,0 +1,17 @@ + diff --git a/catalog/admin/ls.php~ b/catalog/admin/ls.php~ new file mode 100644 index 0000000..b74c052 --- /dev/null +++ b/catalog/admin/ls.php~ @@ -0,0 +1,16 @@ + diff --git a/catalog/admin/make-by-pages.php b/catalog/admin/make-by-pages.php new file mode 100644 index 0000000..0e6f0ba --- /dev/null +++ b/catalog/admin/make-by-pages.php @@ -0,0 +1,618 @@ +page_encoding = "UTF-8"; + +function _navbar ($what, $dir) { + global $config; + $nav = "

$what:\n"; + foreach ($config->browse_pages as $caption => $regexp) { + $href = strtolower ($caption); + $nav .= " $caption \n"; + } + $nav .= "

\n"; + return $nav; +} + +function _navbarrecent ($what, $dir) { + global $spans; + $nav .= "

$what:\n"; + foreach ($spans as $href => $caption) { + $nav .= " $caption \n"; + } + $nav .= "

\n"; + return $nav; +} + +function _navbarlangs ($what, $where, $dir) { + global $db; + $nav = "

$what:\n"; + $db->Exec ("select pk, lang, cnt from langs join (select fk_langs, count (fk_langs) as cnt from mn_books_langs group by fk_langs having count (fk_langs) $where) as sums on pk = fk_langs order by lang;"); + if ($db->FirstRow ()) { + do { + $pk = strtolower ($db->Get ("pk", SQLCHAR)); + $lang = $db->Get ("lang", SQLCHAR); + $cnt = $db->Get ("cnt", SQLINT); + $nav .= " $lang \n"; + } while ($db->NextRow ()); + } + $nav .= "

\n"; + return $nav; +} + +function _navbarloccs ($what, $dir) { + global $db; + $nav = "

$what:\n"; + $db->Exec ("select pk, locc, cnt from loccs join (select fk_loccs, count (fk_loccs) as cnt from mn_books_loccs group by fk_loccs) as sums on pk = fk_loccs order by fk_loccs;"); + if ($db->FirstRow ()) { + do { + $pk = strtolower ($db->Get ("pk", SQLCHAR)); + $pku = strtoupper ($pk); + $locc = $db->Get ("locc", SQLCHAR); + $cnt = $db->Get ("cnt", SQLINT); + $nav .= " $pku \n"; + } while ($db->NextRow ()); + } + $nav .= "

\n"; + return $nav; +} + +function _navbarcategories ($what, $dir) { + global $db; + $nav = "

$what:\n"; + $db->Exec ("select pk, category, cnt from categories join (select fk_categories, count (fk_categories) as cnt from mn_books_categories group by fk_categories) as sums on pk = fk_categories order by category;"); + if ($db->FirstRow ()) { + do { + $pk = $db->Get ("pk", SQLINT); + $category = $db->Get ("category", SQLCHAR); + $cnt = $db->Get ("cnt", SQLINT); + $nav .= " $category \n"; + } while ($db->NextRow ()); + } + $nav .= "

\n"; + return $nav; +} + +function navbar () { + global $dir_authors, $dir_titles, $dir_langs, $dir_loccs, $dir_categories, $dir_recent, $lang_thres; + $nav = "
\n"; + $nav .= _navbar ("Authors", $dir_authors); + $nav .= _navbar ("Titles", $dir_titles); + $nav .= _navbarlangs ("Languages with more than $lang_thres books", "> $lang_thres", $dir_langs); + $nav .= _navbarlangs ("Languages with up to $lang_thres books", "<= $lang_thres", $dir_langs); + // $nav .= _navbarloccs ("LoC Class", $dir_loccs); + $nav .= _navbarcategories ("Special Categories", $dir_categories); + $nav .= _navbarrecent ("Recent", $dir_recent); + $nav .= "
\n\n"; + return $nav; +} + +function pagefooterfile ($file) { + global $page; + $page->footer (); + + $output = ob_get_contents (); + ob_clean (); + + $hd = fopen ($file, "w"); + if ($hd) { + fwrite ($hd, $output); + fclose ($hd); + } + + $hd = gzopen ("$file.gzip", "w9"); + if ($hd) { + gzwrite ($hd, $output); + gzclose ($hd); + } +} + +function LoadTitles () { + global $db, $authors; + + foreach ($authors as $fk_authors => $dummy) { + $authors[$fk_authors]['titles'] = array (); + // echo ("$fk_authors\n"); + } + if ($db->FirstRow ()) { + do { + $o = array (); + $fk_authors = $db->get ("fk_authors", SQLINT); + if (empty ($fk_authors)) + $fk_authors = 0; + // echo ("fk_authors: $fk_authors\n"); + $o['title'] = str_replace ("\n", "endtag>", + strip_marc_subfields (htmlspecialchars ($db->get ("title", SQLCHAR)))); + $o['lang'] = $db->get ("lang", SQLCHAR); + $o['etext'] = $db->get ("fk_books", SQLINT); + $o['is_audio'] = $db->get ("is_audio", SQLBOOL); + $o['role'] = $db->get ("role", SQLCHAR); + array_push ($authors[$fk_authors]['titles'], $o); + } while ($db->NextRow ()); + } +} + +function pklist ($aa) { + // make a list of all authors with titles + $pklist = array (); + foreach ($aa as $fk_authors => $o) { + if (count ($o['titles'])) { + $pklist[] = $fk_authors; + } + } + return $pklist; +} + +function FormatAliases ($pklist, $mode = 0, $regex = "") { + global $db, $lines, $authors; + + if (count ($pklist) == 0) + return; + + $list = join (",", $pklist); + $db->exec ("select fk_authors, alias from aliases " . + "where aliases.alias_heading = 1 and fk_authors in ($list)"); + + if ($db->FirstRow ()) { + do { + $fk_authors = $db->get ("fk_authors", SQLINT); + $alias = $db->get ("alias", SQLCHAR); + $author = $authors[$fk_authors]['author']; + if ($mode == 1) { + if (!preg_match ("/$regex/i", $alias)) + continue; + // the by-author pages need a different url + $href = find_browse_page ($author) . "#a$fk_authors"; + } else { + $href = "#a$fk_authors"; + } + $html_alias = htmlspecialchars ($alias); + $html_author = htmlspecialchars ($author); + $lines[$alias] = "

$html_alias

\n

See: $html_author

\n\n"; + // echo ("$alias\n"); + } while ($db->NextRow ()); + } +} + +function FormatAuthors ($mode = 0) { + global $db, $lines, $dir_etext, $authors; + + foreach ($authors as $fk_authors => $o) { + if (count ($o['titles'])) { + $html_author = htmlspecialchars ($o['author']); + if ($mode == 1 || $fk_authors == 0) { + $line = "

$html_author ¶

\n"; + } else { + $href = "/browse/authors/" . find_browse_page ($o['author']) . "#a$fk_authors"; + $line = "

$html_author

\n"; + } + $line .= "\n\n"; + $lines[$o['author']] = $line; + // echo ("{$o['author']}\n"); + } + } +} + +$dir = "browse"; +$dir_authors = "$dir/authors"; +$dir_titles = "$dir/titles"; +$dir_langs = "$dir/languages"; +$dir_loccs = "$dir/loccs"; +$dir_subjects = "$dir/subjects"; +$dir_categories = "$dir/categories"; +$dir_recent = "$dir/recent"; +$dir_feeds = "cache/epub/feeds"; +$dir_etext = "ebooks"; +$base_url = "http://$config->domain"; + +@mkdir ("$config->documentroot/$dir", 0755); +@mkdir ("$config->documentroot/$dir_authors", 0755); +@mkdir ("$config->documentroot/$dir_titles", 0755); +@mkdir ("$config->documentroot/$dir_langs", 0755); +@mkdir ("$config->documentroot/$dir_loccs", 0755); +@mkdir ("$config->documentroot/$dir_subjects", 0755); +@mkdir ("$config->documentroot/$dir_categories", 0755); +@mkdir ("$config->documentroot/$dir_recent", 0755); +@mkdir ("$config->documentroot/$dir_feeds", 0755); + +$spans[1] = 'last 24 hours'; +$spans[7] = 'last 7 days'; +$spans[30] = 'last 30 days'; + +$db = $config->db (); +$db2 = $config->db (); +$authors = array (); + +//////////////////////////////////////////////////////////////////////// +// load authors + +$authors[0]['author'] = "No Author Listed"; + +$db->exec ("select * from authors"); +if ($db->FirstRow ()) { + do { + $fk_authors = $db->get ("pk", SQLINT); + $authors[$fk_authors]['author'] = FormatAuthorDate ($db); + } while ($db->NextRow ()); +} + +$db->exec ("select * from aliases where alias_heading = 1 order by alias"); +if ($db->FirstRow ()) { + do { + $fk_authors = $db->get ("fk_authors", SQLINT); + $alias = htmlspecialchars ($db->get ("alias", SQLCHAR)); + $authors[$fk_authors]['aliases'][] = $alias; + } while ($db->NextRow ()); +} + +$db->exec ("select * from author_urls order by description"); +if ($db->FirstRow ()) { + do { + $fk_authors = $db->get ("fk_authors", SQLINT); + $description = htmlspecialchars ($db->get ("description", SQLCHAR)); + $url = htmlspecialchars ($db->get ("url", SQLCHAR)); + $authors[$fk_authors]['urls'][$description] = $url; + } while ($db->NextRow ()); +} + +// echo ("$config->documentroot/$dir/navbar.html\n"); +if ($hd = fopen ("$config->documentroot/$dir/navbar.html", "w")) { + fputs ($hd, navbar ()); + fclose ($hd); +} + +//////////////////////////////////////////////////////////////////////////////// + +$db->exec ("create temporary table tmp_books as select * from v_books"); + +//////////////////////////////////////////////////////////////////////////////// +// by-author + +// Postgres 7.3.3 at ibiblio doesn't dig multicolumn functional indexes +$db->exec ("create index tmp_ix_books_authors on tmp_books (lower (author))"); + +foreach ($config->browse_pages as $caption => $regexp) { + + // titles for each author + $db->exec ("select * from tmp_books where author ~* '^$regexp' " . + "order by author, filing, lang"); + LoadTitles (); + + $lines = array (); + FormatAuthors (1); + + $pklist = array (); + $db->exec ("select fk_authors from aliases where alias ~* '^$regexp'"); + if ($db->FirstRow ()) { + do { + $pklist[] = $db->get ("fk_authors", SQLINT); + } while ($db->NextRow ()); + } + FormatAliases ($pklist, 1, "^$regexp"); + uksort ($lines, 'strcoll'); + + $fn = strtolower ($caption); + + pageheader ("Browse By Author: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + foreach ($lines as $line) { + echo ($line); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_authors/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// by-lang + +$db->exec ("create index tmp_ix_books_langs on tmp_books (lang)"); + +$db->exec ("select pk, lang from langs where pk in (select fk_langs from mn_books_langs)"); + +if ($db->FirstRow ()) { + do { + $langs[$db->get ("lang", SQLCHAR)] = $db->get ("pk", SQLCHAR); + } while ($db->NextRow ()); +} + +foreach ($langs as $lang => $id) { + $caption = $lang; + $fn = $id; + + if ($id == 'en') { + pageheader ("Browse By Language: $caption"); + echo (navbar ()); + echo ("

There are too many english books to list them in one page. " . + "Please use the Browse-By-Author pages instead.

\n\n"); + pagefooterfile ("$config->documentroot/$dir_langs/$fn.html.utf8"); + continue; + } + + $db->exec ("select * from tmp_books where fk_books in +(select fk_books from mn_books_langs where fk_langs = '$id' +and tmp_books.fk_books = mn_books_langs.fk_books) +order by lang, author, filing"); + + LoadTitles (); + + $lines = array (); + FormatAuthors (); + FormatAliases (pklist ($authors)); + uksort ($lines, 'strcoll'); + + pageheader ("Browse By Language: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + foreach ($lines as $line) { + echo ($line); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_langs/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// by-locc + +$db->exec ("select pk, locc from loccs where pk in (select fk_loccs from mn_books_loccs)"); + +if ($db->FirstRow ()) { + do { + $loccs[$db->get ("locc", SQLCHAR)] = $db->get ("pk", SQLCHAR); + } while ($db->NextRow ()); +} + +foreach ($loccs as $locc => $fk_loccs) { + $caption = $locc; + $fn = strtolower ($fk_loccs); + + // titles for each author + // $db->exec ("select * from tmp_books where fk_loccs = '$fk_loccs' " . + // "order by fk_loccs, author, filing"); + $db->exec ("select * from tmp_books where fk_books in +(select fk_books from mn_books_loccs where fk_loccs = '$fk_loccs' +and tmp_books.fk_books = mn_books_loccs.fk_books) +order by author, filing"); + + LoadTitles (); + + $lines = array (); + FormatAuthors (); + FormatAliases (pklist ($authors)); + uksort ($lines, 'strcoll'); + + pageheader ("Browse By Library of Congress Class: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + foreach ($lines as $line) { + echo ($line); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_loccs/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// by-category + +$db->exec ("select pk, category from categories"); + +if ($db->FirstRow ()) { + do { + $categories[$db->get ("category", SQLCHAR)] = $db->get ("pk", SQLINT); + } while ($db->NextRow ()); +} + +foreach ($categories as $category => $id) { + $caption = $category; + $fn = $id; + + if ($id == 0) { + pageheader ("Browse By Category: $caption"); + echo (navbar ()); + echo ("

There are too many books in this category too list them in one page. " . + "Please use the Browse-By-Author pages instead.

\n\n"); + pagefooterfile ("$config->documentroot/$dir_langs/$fn.html.utf8"); + continue; + } + + $db->exec ("select * from tmp_books where fk_books in +(select fk_books from mn_books_categories where fk_categories = $id +and tmp_books.fk_books = mn_books_categories.fk_books) +order by author, filing"); + LoadTitles (); + + $lines = array (); + FormatAuthors (); + FormatAliases (pklist ($authors)); + uksort ($lines, 'strcoll'); + + pageheader ("Browse By Category: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + foreach ($lines as $line) { + echo ($line); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_categories/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// by-title + +$db->exec ("create index tmp_ix_books_titles on tmp_books (lower (filing))"); + +foreach ($config->browse_pages as $caption => $regexp) { + $fn = strtolower ($caption); + pageheader ("Browse By Title: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + // titles + $db->exec ("select * from tmp_books where lower (filing) ~ '^$regexp' order by lower (filing), author, lang"); + + if ($db->FirstRow ()) { + do { + $etext = $db->get ("fk_books", SQLINT); + $fk_authors = $db->get ("fk_authors", SQLINT); + $title = str_replace ("\n", "endtag>", $db->get ("title", SQLCHAR)); + $author = $db->get ("author", SQLCHAR); + $lang = $db->get ("lang", SQLCHAR); + $is_audio = $db->get ("is_audio", SQLBOOL); + // echo ("$title\n"); + $icon = $is_audio ? " \"Audioendtag>" : ""; + echo ("

$title ($lang)$icon

\n"); + $href = "/$dir_authors/" . find_browse_page ($author) . "#a$fk_authors"; + echo ("

by $author

\n\n"); + } while ($db->NextRow ()); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_titles/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// recent books + +$db->exec ("create index tmp_ix_books_fk_books on tmp_books (fk_books)"); +$rssbuffer = ""; +$books_output = array (); + +// clear titles +foreach ($authors as $fk_authors => $dummy) { + $authors[$fk_authors]['titles'] = array (); +} + +foreach ($spans as $span => $caption) { + + $recents = array (); + $cutoff = date ("Y-m-d", time () - $span * 86400); + + $db->exec ("select distinct fk_books from files " . + "where fk_books is not null and diskstatus = 0 and filename !~ '^cache' and filemtime >= '$cutoff 00:00:00'"); + if ($db->FirstRow ()) { + do { + $recents[] = $db->get ("fk_books", SQLINT); + } while ($db->NextRow ()); + } + + $lines = array (); + + if (count ($recents)) { + $recent = join (", ", $recents); + + // titles for each author + $db->exec ("select * from tmp_books where fk_books in ($recent) order by author, filing, lang"); + LoadTitles (); + + FormatAuthors (); + FormatAliases (pklist ($authors)); + uksort ($lines, 'strcoll'); + } + + $config->htmlheaderlinks[] = ""; + pageheader ("Books Posted or Updated Since: $cutoff"); + echo (navbar ()); + echo ("
\n\n"); + + if (!count ($recents)) { + echo ("

No books posted.

\n\n"); + } + foreach ($lines as $line) { + echo ($line); + } + if ($span == 1) { + // build rss + foreach ($authors as $author => $o) { + if (count ($o['titles'])) { + // output list of titles + foreach ($o['titles'] as $t) { + // avoid duplicates in rss + if (!isset ($books_output[$t['etext']])) { + $books_output[$t['etext']] = 1; + $friendlytitle = htmlspecialchars (friendlytitle ($t['etext'], 100)); + $rssbuffer .= " \n"; + $rssbuffer .= " $friendlytitle\n"; + $rssbuffer .= " $base_url/$dir_etext/{$t['etext']}\n"; + $rssbuffer .= " Language: {$t['lang']}\n"; + $rssbuffer .= " \n\n"; + } + } + } + } + } + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_recent/last$span.html.utf8"); + + $config->htmlheaderlinks = array (); +} + +// write rss feed +if ($hd = fopen ($file = "$config->documentroot/$dir_feeds/today.rss", "w")) { + $pubdate = date ("r"); + + fputs ($hd, << + + + Project Gutenberg Recently Posted or Updated EBooks + $base_url + + EBooks posted or updated today on Project Gutenberg. + This feed is regenerated every night. + + en-us + webmaster@gutenberg.org (Marcello Perathoner) + $pubdate + $pubdate + +EOF +); + + fputs ($hd, $rssbuffer); + fputs ($hd, " \n\n"); + fclose ($hd); +} + +?> diff --git a/catalog/admin/make-by-pages.php~ b/catalog/admin/make-by-pages.php~ new file mode 100644 index 0000000..d9311fe --- /dev/null +++ b/catalog/admin/make-by-pages.php~ @@ -0,0 +1,617 @@ +page_encoding = "UTF-8"; + +function _navbar ($what, $dir) { + global $config; + $nav = "

$what:\n"; + foreach ($config->browse_pages as $caption => $regexp) { + $href = strtolower ($caption); + $nav .= " $caption \n"; + } + $nav .= "

\n"; + return $nav; +} + +function _navbarrecent ($what, $dir) { + global $spans; + $nav .= "

$what:\n"; + foreach ($spans as $href => $caption) { + $nav .= " $caption \n"; + } + $nav .= "

\n"; + return $nav; +} + +function _navbarlangs ($what, $where, $dir) { + global $db; + $nav = "

$what:\n"; + $db->Exec ("select pk, lang, cnt from langs join (select fk_langs, count (fk_langs) as cnt from mn_books_langs group by fk_langs having count (fk_langs) $where) as sums on pk = fk_langs order by lang;"); + if ($db->FirstRow ()) { + do { + $pk = strtolower ($db->Get ("pk", SQLCHAR)); + $lang = $db->Get ("lang", SQLCHAR); + $cnt = $db->Get ("cnt", SQLINT); + $nav .= " $lang \n"; + } while ($db->NextRow ()); + } + $nav .= "

\n"; + return $nav; +} + +function _navbarloccs ($what, $dir) { + global $db; + $nav = "

$what:\n"; + $db->Exec ("select pk, locc, cnt from loccs join (select fk_loccs, count (fk_loccs) as cnt from mn_books_loccs group by fk_loccs) as sums on pk = fk_loccs order by fk_loccs;"); + if ($db->FirstRow ()) { + do { + $pk = strtolower ($db->Get ("pk", SQLCHAR)); + $pku = strtoupper ($pk); + $locc = $db->Get ("locc", SQLCHAR); + $cnt = $db->Get ("cnt", SQLINT); + $nav .= " $pku \n"; + } while ($db->NextRow ()); + } + $nav .= "

\n"; + return $nav; +} + +function _navbarcategories ($what, $dir) { + global $db; + $nav = "

$what:\n"; + $db->Exec ("select pk, category, cnt from categories join (select fk_categories, count (fk_categories) as cnt from mn_books_categories group by fk_categories) as sums on pk = fk_categories order by category;"); + if ($db->FirstRow ()) { + do { + $pk = $db->Get ("pk", SQLINT); + $category = $db->Get ("category", SQLCHAR); + $cnt = $db->Get ("cnt", SQLINT); + $nav .= " $category \n"; + } while ($db->NextRow ()); + } + $nav .= "

\n"; + return $nav; +} + +function navbar () { + global $dir_authors, $dir_titles, $dir_langs, $dir_loccs, $dir_categories, $dir_recent, $lang_thres; + $nav = "
\n"; + $nav .= _navbar ("Authors", $dir_authors); + $nav .= _navbar ("Titles", $dir_titles); + $nav .= _navbarlangs ("Languages with more than $lang_thres books", "> $lang_thres", $dir_langs); + $nav .= _navbarlangs ("Languages with up to $lang_thres books", "<= $lang_thres", $dir_langs); + // $nav .= _navbarloccs ("LoC Class", $dir_loccs); + $nav .= _navbarcategories ("Special Categories", $dir_categories); + $nav .= _navbarrecent ("Recent", $dir_recent); + $nav .= "
\n\n"; + return $nav; +} + +function pagefooterfile ($file) { + global $page; + $page->footer (); + + $output = ob_get_contents (); + ob_clean (); + + $hd = fopen ($file, "w"); + if ($hd) { + fwrite ($hd, $output); + fclose ($hd); + } + + $hd = gzopen ("$file.gzip", "w9"); + if ($hd) { + gzwrite ($hd, $output); + gzclose ($hd); + } +} + +function LoadTitles () { + global $db, $authors; + + foreach ($authors as $fk_authors => $dummy) { + $authors[$fk_authors]['titles'] = array (); + // echo ("$fk_authors\n"); + } + if ($db->FirstRow ()) { + do { + $o = array (); + $fk_authors = $db->get ("fk_authors", SQLINT); + if (empty ($fk_authors)) + $fk_authors = 0; + // echo ("fk_authors: $fk_authors\n"); + $o['title'] = str_replace ("\n", "endtag>", + strip_marc_subfields (htmlspecialchars ($db->get ("title", SQLCHAR)))); + $o['lang'] = $db->get ("lang", SQLCHAR); + $o['etext'] = $db->get ("fk_books", SQLINT); + $o['is_audio'] = $db->get ("is_audio", SQLBOOL); + $o['role'] = $db->get ("role", SQLCHAR); + array_push ($authors[$fk_authors]['titles'], $o); + } while ($db->NextRow ()); + } +} + +function pklist ($aa) { + // make a list of all authors with titles + $pklist = array (); + foreach ($aa as $fk_authors => $o) { + if (count ($o['titles'])) { + $pklist[] = $fk_authors; + } + } + return $pklist; +} + +function FormatAliases ($pklist, $mode = 0, $regex = "") { + global $db, $lines, $authors; + + if (count ($pklist) == 0) + return; + + $list = join (",", $pklist); + $db->exec ("select fk_authors, alias from aliases " . + "where aliases.alias_heading = 1 and fk_authors in ($list)"); + + if ($db->FirstRow ()) { + do { + $fk_authors = $db->get ("fk_authors", SQLINT); + $alias = $db->get ("alias", SQLCHAR); + $author = $authors[$fk_authors]['author']; + if ($mode == 1) { + if (!preg_match ("/$regex/i", $alias)) + continue; + // the by-author pages need a different url + $href = find_browse_page ($author) . "#a$fk_authors"; + } else { + $href = "#a$fk_authors"; + } + $html_alias = htmlspecialchars ($alias); + $html_author = htmlspecialchars ($author); + $lines[$alias] = "

$html_alias

\n

See: $html_author

\n\n"; + // echo ("$alias\n"); + } while ($db->NextRow ()); + } +} + +function FormatAuthors ($mode = 0) { + global $db, $lines, $dir_etext, $authors; + + foreach ($authors as $fk_authors => $o) { + if (count ($o['titles'])) { + $html_author = htmlspecialchars ($o['author']); + if ($mode == 1 || $fk_authors == 0) { + $line = "

$html_author ¶

\n"; + } else { + $href = "/browse/authors/" . find_browse_page ($o['author']) . "#a$fk_authors"; + $line = "

$html_author

\n"; + } + $line .= "
    \n"; + + if ($mode == 1) { + // by-author page + if (isset ($o['aliases'])) { + foreach ($o['aliases'] as $alias) { + $line .= "
  • $alias
  • \n"; + } + } + + if (isset ($o['urls'])) { + foreach ($o['urls'] as $description => $url) { + $line .= "
  • $description
  • \n"; + } + } + } + + // output list of titles + foreach ($o['titles'] as $t) { + $role = (empty ($t['role']) || $t['role'] == "Creator") ? "" : " (as {$t['role']})"; + $cls = $t['is_audio'] ? " class=\"pgdbaudio\"" : " class=\"pgdbetext\""; + $line .= " {$t['title']} ({$t['lang']})$role\n"; + } + $line .= "
\n\n"; + $lines[$o['author']] = $line; + // echo ("{$o['author']}\n"); + } + } +} + +$dir = "browse"; +$dir_authors = "$dir/authors"; +$dir_titles = "$dir/titles"; +$dir_langs = "$dir/languages"; +$dir_loccs = "$dir/loccs"; +$dir_subjects = "$dir/subjects"; +$dir_categories = "$dir/categories"; +$dir_recent = "$dir/recent"; +$dir_feeds = "cache/epub/feeds"; +$dir_etext = "ebooks"; +$base_url = "http://$config->domain"; + +@mkdir ("$config->documentroot/$dir", 0755); +@mkdir ("$config->documentroot/$dir_authors", 0755); +@mkdir ("$config->documentroot/$dir_titles", 0755); +@mkdir ("$config->documentroot/$dir_langs", 0755); +@mkdir ("$config->documentroot/$dir_loccs", 0755); +@mkdir ("$config->documentroot/$dir_subjects", 0755); +@mkdir ("$config->documentroot/$dir_categories", 0755); +@mkdir ("$config->documentroot/$dir_recent", 0755); +@mkdir ("$config->documentroot/$dir_feeds", 0755); + +$spans[1] = 'last 24 hours'; +$spans[7] = 'last 7 days'; +$spans[30] = 'last 30 days'; + +$db = $config->db (); +$db2 = $config->db (); +$authors = array (); + +//////////////////////////////////////////////////////////////////////// +// load authors + +$authors[0]['author'] = "No Author Listed"; + +$db->exec ("select * from authors"); +if ($db->FirstRow ()) { + do { + $fk_authors = $db->get ("pk", SQLINT); + $authors[$fk_authors]['author'] = FormatAuthorDate ($db); + } while ($db->NextRow ()); +} + +$db->exec ("select * from aliases where alias_heading = 1 order by alias"); +if ($db->FirstRow ()) { + do { + $fk_authors = $db->get ("fk_authors", SQLINT); + $alias = htmlspecialchars ($db->get ("alias", SQLCHAR)); + $authors[$fk_authors]['aliases'][] = $alias; + } while ($db->NextRow ()); +} + +$db->exec ("select * from author_urls order by description"); +if ($db->FirstRow ()) { + do { + $fk_authors = $db->get ("fk_authors", SQLINT); + $description = htmlspecialchars ($db->get ("description", SQLCHAR)); + $url = htmlspecialchars ($db->get ("url", SQLCHAR)); + $authors[$fk_authors]['urls'][$description] = $url; + } while ($db->NextRow ()); +} + +// echo ("$config->documentroot/$dir/navbar.html\n"); +if ($hd = fopen ("$config->documentroot/$dir/navbar.html", "w")) { + fputs ($hd, navbar ()); + fclose ($hd); +} + +//////////////////////////////////////////////////////////////////////////////// + +$db->exec ("create temporary table tmp_books as select * from v_books"); + +//////////////////////////////////////////////////////////////////////////////// +// by-author + +// Postgres 7.3.3 at ibiblio doesn't dig multicolumn functional indexes +$db->exec ("create index tmp_ix_books_authors on tmp_books (lower (author))"); + +foreach ($config->browse_pages as $caption => $regexp) { + + // titles for each author + $db->exec ("select * from tmp_books where author ~* '^$regexp' " . + "order by author, filing, lang"); + LoadTitles (); + + $lines = array (); + FormatAuthors (1); + + $pklist = array (); + $db->exec ("select fk_authors from aliases where alias ~* '^$regexp'"); + if ($db->FirstRow ()) { + do { + $pklist[] = $db->get ("fk_authors", SQLINT); + } while ($db->NextRow ()); + } + FormatAliases ($pklist, 1, "^$regexp"); + uksort ($lines, 'strcoll'); + + $fn = strtolower ($caption); + + pageheader ("Browse By Author: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + foreach ($lines as $line) { + echo ($line); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_authors/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// by-lang + +$db->exec ("create index tmp_ix_books_langs on tmp_books (lang)"); + +$db->exec ("select pk, lang from langs where pk in (select fk_langs from mn_books_langs)"); + +if ($db->FirstRow ()) { + do { + $langs[$db->get ("lang", SQLCHAR)] = $db->get ("pk", SQLCHAR); + } while ($db->NextRow ()); +} + +foreach ($langs as $lang => $id) { + $caption = $lang; + $fn = $id; + + if ($id == 'en') { + pageheader ("Browse By Language: $caption"); + echo (navbar ()); + echo ("

There are too many english books to list them in one page. " . + "Please use the Browse-By-Author pages instead.

\n\n"); + pagefooterfile ("$config->documentroot/$dir_langs/$fn.html.utf8"); + continue; + } + + $db->exec ("select * from tmp_books where fk_books in +(select fk_books from mn_books_langs where fk_langs = '$id' +and tmp_books.fk_books = mn_books_langs.fk_books) +order by lang, author, filing"); + + LoadTitles (); + + $lines = array (); + FormatAuthors (); + FormatAliases (pklist ($authors)); + uksort ($lines, 'strcoll'); + + pageheader ("Browse By Language: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + foreach ($lines as $line) { + echo ($line); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_langs/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// by-locc + +$db->exec ("select pk, locc from loccs where pk in (select fk_loccs from mn_books_loccs)"); + +if ($db->FirstRow ()) { + do { + $loccs[$db->get ("locc", SQLCHAR)] = $db->get ("pk", SQLCHAR); + } while ($db->NextRow ()); +} + +foreach ($loccs as $locc => $fk_loccs) { + $caption = $locc; + $fn = strtolower ($fk_loccs); + + // titles for each author + // $db->exec ("select * from tmp_books where fk_loccs = '$fk_loccs' " . + // "order by fk_loccs, author, filing"); + $db->exec ("select * from tmp_books where fk_books in +(select fk_books from mn_books_loccs where fk_loccs = '$fk_loccs' +and tmp_books.fk_books = mn_books_loccs.fk_books) +order by author, filing"); + + LoadTitles (); + + $lines = array (); + FormatAuthors (); + FormatAliases (pklist ($authors)); + uksort ($lines, 'strcoll'); + + pageheader ("Browse By Library of Congress Class: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + foreach ($lines as $line) { + echo ($line); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_loccs/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// by-category + +$db->exec ("select pk, category from categories"); + +if ($db->FirstRow ()) { + do { + $categories[$db->get ("category", SQLCHAR)] = $db->get ("pk", SQLINT); + } while ($db->NextRow ()); +} + +foreach ($categories as $category => $id) { + $caption = $category; + $fn = $id; + + if ($id == 0) { + pageheader ("Browse By Category: $caption"); + echo (navbar ()); + echo ("

There are too many books in this category too list them in one page. " . + "Please use the Browse-By-Author pages instead.

\n\n"); + pagefooterfile ("$config->documentroot/$dir_langs/$fn.html.utf8"); + continue; + } + + $db->exec ("select * from tmp_books where fk_books in +(select fk_books from mn_books_categories where fk_categories = $id +and tmp_books.fk_books = mn_books_categories.fk_books) +order by author, filing"); + LoadTitles (); + + $lines = array (); + FormatAuthors (); + FormatAliases (pklist ($authors)); + uksort ($lines, 'strcoll'); + + pageheader ("Browse By Category: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + foreach ($lines as $line) { + echo ($line); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_categories/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// by-title + +$db->exec ("create index tmp_ix_books_titles on tmp_books (lower (filing))"); + +foreach ($config->browse_pages as $caption => $regexp) { + $fn = strtolower ($caption); + pageheader ("Browse By Title: $caption"); + echo (navbar ()); + echo ("
\n\n"); + + // titles + $db->exec ("select * from tmp_books where lower (filing) ~ '^$regexp' order by lower (filing), author, lang"); + + if ($db->FirstRow ()) { + do { + $etext = $db->get ("fk_books", SQLINT); + $fk_authors = $db->get ("fk_authors", SQLINT); + $title = str_replace ("\n", "endtag>", $db->get ("title", SQLCHAR)); + $author = $db->get ("author", SQLCHAR); + $lang = $db->get ("lang", SQLCHAR); + $is_audio = $db->get ("is_audio", SQLBOOL); + // echo ("$title\n"); + $icon = $is_audio ? " \"Audioendtag>" : ""; + echo ("

$title ($lang)$icon

\n"); + $href = "/$dir_authors/" . find_browse_page ($author) . "#a$fk_authors"; + echo ("

by $author

\n\n"); + } while ($db->NextRow ()); + } + + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_titles/$fn.html.utf8"); +} + +//////////////////////////////////////////////////////////////////////////////// +// recent books + +$db->exec ("create index tmp_ix_books_fk_books on tmp_books (fk_books)"); +$rssbuffer = ""; +$books_output = array (); + +// clear titles +foreach ($authors as $fk_authors => $dummy) { + $authors[$fk_authors]['titles'] = array (); +} + +foreach ($spans as $span => $caption) { + + $recents = array (); + $cutoff = date ("Y-m-d", time () - $span * 86400); + + $db->exec ("select distinct fk_books from files " . + "where fk_books is not null and diskstatus = 0 and filename !~ '^cache' and filemtime >= '$cutoff 00:00:00'"); + if ($db->FirstRow ()) { + do { + $recents[] = $db->get ("fk_books", SQLINT); + } while ($db->NextRow ()); + } + + $lines = array (); + + if (count ($recents)) { + $recent = join (", ", $recents); + + // titles for each author + $db->exec ("select * from tmp_books where fk_books in ($recent) order by author, filing, lang"); + LoadTitles (); + + FormatAuthors (); + FormatAliases (pklist ($authors)); + uksort ($lines, 'strcoll'); + } + + $config->htmlheaderlinks[] = ""; + pageheader ("Books Posted or Updated Since: $cutoff"); + echo (navbar ()); + echo ("
\n\n"); + + if (!count ($recents)) { + echo ("

No books posted.

\n\n"); + } + foreach ($lines as $line) { + echo ($line); + } + if ($span == 1) { + // build rss + foreach ($authors as $author => $o) { + if (count ($o['titles'])) { + // output list of titles + foreach ($o['titles'] as $t) { + // avoid duplicates in rss + if (!isset ($books_output[$t['etext']])) { + $books_output[$t['etext']] = 1; + $friendlytitle = htmlspecialchars (friendlytitle ($t['etext'], 100)); + $rssbuffer .= " \n"; + $rssbuffer .= " $friendlytitle\n"; + $rssbuffer .= " $base_url/$dir_etext/{$t['etext']}\n"; + $rssbuffer .= " Language: {$t['lang']}\n"; + $rssbuffer .= " \n\n"; + } + } + } + } + } + echo ("
\n\n"); + pagefooterfile ("$config->documentroot/$dir_recent/last$span.html.utf8"); + + $config->htmlheaderlinks = array (); +} + +// write rss feed +if ($hd = fopen ($file = "$config->documentroot/$dir_feeds/today.rss", "w")) { + $pubdate = date ("r"); + + fputs ($hd, << + + + Project Gutenberg Recently Posted or Updated EBooks + $base_url + + EBooks posted or updated today on Project Gutenberg. + This feed is regenerated every night. + + en-us + webmaster@gutenberg.org (Marcello Perathoner) + $pubdate + $pubdate + +EOF +); + + fputs ($hd, $rssbuffer); + fputs ($hd, " \n\n"); + fclose ($hd); +} + +?> diff --git a/catalog/admin/make-rdf.php b/catalog/admin/make-rdf.php new file mode 100644 index 0000000..d4f3d1e --- /dev/null +++ b/catalog/admin/make-rdf.php @@ -0,0 +1,384 @@ + 1) { + $s .= " <$tag>\n \n"; + foreach ($a as $val) { + $s .= " $val\n"; + } + $s .= " \n \n"; + } else { + $val = $a[0]; + $s .= " <$tag rdf:parseType=\"Literal\">$val\n"; + } + } else { + $val = $a; + $s .= " <$tag rdf:parseType=\"Literal\">$val\n"; + } + } + return $s; +} + +function qout (&$book, $name, $tag, $tag2) { + if (!isset ($book[$name])) { + return ""; + } + $a = $book[$name]; + if (is_array ($a)) { + if (count ($a) > 1) { + $s = " <$tag>\n \n"; + foreach ($a as $val) { + $s .= " <$tag2>$val\n"; + } + $s .= " \n \n"; + return $s; + } else { + $val = $a[0]; + return " <$tag><$tag2>$val\n"; + } + } + $val = $a; + return " <$tag><$tag2>$val\n"; +} + +_log ("Initializing ..."); + +$db = $config->db (); + +_log (" Connected to Database ..."); + +$base_url = "http://www.gutenberg.org"; +$file_base = "$base_url"; + +$now = date ("Y-m-d"); + +$books = array (); + +_log (" Done\n"); + +_log ("Loading data from database ..."); + +_log (" Books"); + +$db->exec ("select * from books"); +if ($db->FirstRow ()) { + do { + $pk = $db->get ("pk", SQLINT); + if ($reldate = $db->get ("release_date", SQLDATE)) { + $books[$pk]['release_date'] = date ("Y-m-d", $reldate); + $books[$pk]['downloads'] = $db->get ("downloads", SQLINT); + } + if ($db->get ("copyrighted", SQLINT)) { + $books[$pk]['copyrighted'] = 1; + } + } while ($db->NextRow ()); +} + +_log (" Authors"); + +$db->exec ("select * from v_books_authors order by fk_books"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $role = $db->get ("role", SQLCHAR); + if ($role == "Creator" || $role == "Author") { + $val = htmlspecialchars (FormatAuthorDate ($db)); + $books[$fk_books]['creators'][] = $val; + } else { + $val = htmlspecialchars (FormatAuthorDateRole ($db)); + $books[$fk_books]['contributors'][] = $val; + } + } while ($db->NextRow ()); +} + +_log (" FriendlyTitles"); + +foreach ($books as $fk_books => $dummy) { + $books[$fk_books]['friendlytitle'][] = htmlspecialchars (friendlytitle ($fk_books)); +} + +/* _log (" Titles"); + +$db->exec ("select * from titles"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $title = htmlspecialchars ($db->get ("title", SQLCHAR)); + // $title = preg_replace ("/\s*\n/", "
", $title); + switch ($db->get ("title_order", SQLINT)) { + case 1: + $books[$fk_books]['240'][] = $title; break; + case 2: + case 4: + case 5: + $books[$fk_books]['246'][] = $title; break; + case 3: + $books[$fk_books]['505'][] = $title; break; + } + } while ($db->NextRow ()); +} */ + +_log (" Attributes"); + +$db->exec ("select * from attributes"); + +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $fk_attriblist = (string) $db->get ("fk_attriblist", SQLINT); + $text = htmlspecialchars ($db->get ("text", SQLCHAR)); + $books[$fk_books][$fk_attriblist][] = $text; + } while ($db->NextRow ()); +} + +_log (" Categories"); + +$db->exec ("select * from mn_books_categories, categories where fk_categories = pk"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $books[$fk_books]['categories'][] = $db->get ("category", SQLCHAR); + } while ($db->NextRow ()); +} else { + $books[$fk_books]['categories'][] = 'eBook'; +} + +_log (" Languages"); + +$db->exec ("select * from mn_books_langs"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $books[$fk_books]['languages'][] = $db->get ("fk_langs", SQLCHAR); + } while ($db->NextRow ()); +} + +_log (" Subjects"); + +$db->exec ("select * from mn_books_subjects, subjects where fk_subjects = pk"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $subject = htmlspecialchars ($db->get ("subject", SQLCHAR)); + $books[$fk_books]['subjects'][] = $subject; + } while ($db->NextRow ()); +} + +_log (" LoCC"); + +$db->exec ("select * from mn_books_loccs"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $books[$fk_books]['loccs'][] = $db->get ("fk_loccs", SQLCHAR); + } while ($db->NextRow ()); +} + +_log (" Done\n"); + +$fp = fopen ("php://stdout", "w"); + +$s = <<< EOF + + + + + +]> + + + + + + + + + + + + + + + + + + + + $now + + + +EOF; + +fputs ($fp, $s); + +// debug +// $books = array_slice ($books, 0, 500); + +reset ($books); + +while (list ($fk_books, $book) = each ($books)) { + $s = "\n"; + $s .= " &pg;\n"; + + $s .= lout ($book, '240', 'dc:title'); + $s .= lout ($book, '245', 'dc:title'); + $s .= lout ($book, '246', 'dc:alternative'); + $s .= lout ($book, '500', 'dc:description'); + $s .= lout ($book, '505', 'dc:tableOfContents'); + + $s .= lout ($book, 'creators', 'dc:creator'); + $s .= lout ($book, 'contributors', 'dc:contributor'); + $s .= lout ($book, 'friendlytitle', 'pgterms:friendlytitle'); + + $s .= qout ($book, 'languages', 'dc:language', 'dcterms:ISO639-2'); + $s .= qout ($book, 'subjects', 'dc:subject', 'dcterms:LCSH'); + $s .= qout ($book, 'loccs', 'dc:subject', 'dcterms:LCC'); + $s .= qout ($book, 'release_date', 'dc:created', 'dcterms:W3CDTF'); + $s .= qout ($book, 'downloads', 'pgterms:downloads', 'xsd:nonNegativeInteger'); + $s .= qout ($book, 'categories', 'dc:type', 'pgterms:category'); + + if (isset ($book['copyrighted'])) { + $s .= " Copyrighted work. See license inside work.\n"; + } else { + $s .= " \n"; + } + + $s .= "\n\n"; + fputs ($fp, $s); +} + +$books = null; + +// files + +$db->exec ("select fk_books, mediatype, filetype, fk_filetypes, fk_compressions, fk_encodings, " . + "edition, filename, filesize, filemtime " . + "from files " . + "left join filetypes on files.fk_filetypes = filetypes.pk " . + "where fk_books is not null and obsoleted = 0 and diskstatus = 0 " . + "order by fk_books, filename;"); + + +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $filename = $db->get ("filename", SQLCHAR); + $filesize = $db->get ("filesize", SQLINT); + $filetype = $db->get ("filetype", SQLCHAR); + $fk_filetypes = $db->get ("fk_filetypes", SQLCHAR); + $filemtime = $db->get ("filemtime", SQLDATE); + $mediatype = $db->get ("mediatype", SQLCHAR); + $fk_encodings = $db->get ("fk_encodings", SQLCHAR); + $fk_compressions = $db->get ("fk_compressions", SQLCHAR); + + if (!strncmp ($filename, "cache/", 6)) { + $filename = "&f;$filename"; + } else { + $filename = "&f;dirs/$filename"; + } + + $mtime = date ("Y-m-d", $filemtime); + + if (!empty ($fk_encodings) && !strncmp ($mediatype, "text/", 5)) { + $mediatype .= "; charset=\"$fk_encodings\""; + } + if (empty ($mediatype)) { + $mediatype = "application/octet-stream"; + if (!empty ($fk_filetypes)) { + $mediatype .= "; type=\"$filetype ($fk_filetypes)\""; + } + } + $compression = ""; + if ($fk_compressions == "zip") { + $compression = "\n application/zip"; + } + + $s = " + + $mediatype$compression + $filesize + $mtime + + +"; + fputs ($fp, $s); + + } while ($db->NextRow ()); +} + +fputs ($fp, "\n\n"); + +fclose ($fp); + +_log (" Done!\n"); + +?> diff --git a/catalog/admin/make-rdf.php~ b/catalog/admin/make-rdf.php~ new file mode 100644 index 0000000..1ecccd1 --- /dev/null +++ b/catalog/admin/make-rdf.php~ @@ -0,0 +1,383 @@ + 1) { + $s .= " <$tag>\n \n"; + foreach ($a as $val) { + $s .= " $val\n"; + } + $s .= " \n \n"; + } else { + $val = $a[0]; + $s .= " <$tag rdf:parseType=\"Literal\">$val\n"; + } + } else { + $val = $a; + $s .= " <$tag rdf:parseType=\"Literal\">$val\n"; + } + } + return $s; +} + +function qout (&$book, $name, $tag, $tag2) { + if (!isset ($book[$name])) { + return ""; + } + $a = $book[$name]; + if (is_array ($a)) { + if (count ($a) > 1) { + $s = " <$tag>\n \n"; + foreach ($a as $val) { + $s .= " <$tag2>$val\n"; + } + $s .= " \n \n"; + return $s; + } else { + $val = $a[0]; + return " <$tag><$tag2>$val\n"; + } + } + $val = $a; + return " <$tag><$tag2>$val\n"; +} + +_log ("Initializing ..."); + +$db = $config->db (); + +_log (" Connected to Database ..."); + +$base_url = "http://www.gutenberg.org"; +$file_base = "$base_url"; + +$now = date ("Y-m-d"); + +$books = array (); + +_log (" Done\n"); + +_log ("Loading data from database ..."); + +_log (" Books"); + +$db->exec ("select * from books"); +if ($db->FirstRow ()) { + do { + $pk = $db->get ("pk", SQLINT); + if ($reldate = $db->get ("release_date", SQLDATE)) { + $books[$pk]['release_date'] = date ("Y-m-d", $reldate); + $books[$pk]['downloads'] = $db->get ("downloads", SQLINT); + } + if ($db->get ("copyrighted", SQLINT)) { + $books[$pk]['copyrighted'] = 1; + } + } while ($db->NextRow ()); +} + +_log (" Authors"); + +$db->exec ("select * from v_books_authors order by fk_books"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $role = $db->get ("role", SQLCHAR); + if ($role == "Creator" || $role == "Author") { + $val = htmlspecialchars (FormatAuthorDate ($db)); + $books[$fk_books]['creators'][] = $val; + } else { + $val = htmlspecialchars (FormatAuthorDateRole ($db)); + $books[$fk_books]['contributors'][] = $val; + } + } while ($db->NextRow ()); +} + +_log (" FriendlyTitles"); + +foreach ($books as $fk_books => $dummy) { + $books[$fk_books]['friendlytitle'][] = htmlspecialchars (friendlytitle ($fk_books)); +} + +/* _log (" Titles"); + +$db->exec ("select * from titles"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $title = htmlspecialchars ($db->get ("title", SQLCHAR)); + // $title = preg_replace ("/\s*\n/", "
", $title); + switch ($db->get ("title_order", SQLINT)) { + case 1: + $books[$fk_books]['240'][] = $title; break; + case 2: + case 4: + case 5: + $books[$fk_books]['246'][] = $title; break; + case 3: + $books[$fk_books]['505'][] = $title; break; + } + } while ($db->NextRow ()); +} */ + +_log (" Attributes"); + +$db->exec ("select * from attributes"); + +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $fk_attriblist = (string) $db->get ("fk_attriblist", SQLINT); + $text = htmlspecialchars ($db->get ("text", SQLCHAR)); + $books[$fk_books][$fk_attriblist][] = $text; + } while ($db->NextRow ()); +} + +_log (" Categories"); + +$db->exec ("select * from mn_books_categories, categories where fk_categories = pk"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $books[$fk_books]['categories'][] = $db->get ("category", SQLCHAR); + } while ($db->NextRow ()); +} else { + $books[$fk_books]['categories'][] = 'eBook'; +} + +_log (" Languages"); + +$db->exec ("select * from mn_books_langs"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $books[$fk_books]['languages'][] = $db->get ("fk_langs", SQLCHAR); + } while ($db->NextRow ()); +} + +_log (" Subjects"); + +$db->exec ("select * from mn_books_subjects, subjects where fk_subjects = pk"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $subject = htmlspecialchars ($db->get ("subject", SQLCHAR)); + $books[$fk_books]['subjects'][] = $subject; + } while ($db->NextRow ()); +} + +_log (" LoCC"); + +$db->exec ("select * from mn_books_loccs"); +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $books[$fk_books]['loccs'][] = $db->get ("fk_loccs", SQLCHAR); + } while ($db->NextRow ()); +} + +_log (" Done\n"); + +$fp = fopen ("php://stdout", "w"); + +$s = <<< EOF + + + + + +]> + + + + + + + + + + + + + + + + + + + + $now + + + +EOF; + +fputs ($fp, $s); + +// debug +// $books = array_slice ($books, 0, 500); + +reset ($books); + +while (list ($fk_books, $book) = each ($books)) { + $s = "\n"; + $s .= " &pg;\n"; + + $s .= lout ($book, '240', 'dc:title'); + $s .= lout ($book, '245', 'dc:title'); + $s .= lout ($book, '246', 'dc:alternative'); + $s .= lout ($book, '500', 'dc:description'); + $s .= lout ($book, '505', 'dc:tableOfContents'); + + $s .= lout ($book, 'creators', 'dc:creator'); + $s .= lout ($book, 'contributors', 'dc:contributor'); + $s .= lout ($book, 'friendlytitle', 'pgterms:friendlytitle'); + + $s .= qout ($book, 'languages', 'dc:language', 'dcterms:ISO639-2'); + $s .= qout ($book, 'subjects', 'dc:subject', 'dcterms:LCSH'); + $s .= qout ($book, 'loccs', 'dc:subject', 'dcterms:LCC'); + $s .= qout ($book, 'release_date', 'dc:created', 'dcterms:W3CDTF'); + $s .= qout ($book, 'downloads', 'pgterms:downloads', 'xsd:nonNegativeInteger'); + $s .= qout ($book, 'categories', 'dc:type', 'pgterms:category'); + + if (isset ($book['copyrighted'])) { + $s .= " Copyrighted work. See license inside work.\n"; + } else { + $s .= " \n"; + } + + $s .= "\n\n"; + fputs ($fp, $s); +} + +$books = null; + +// files + +$db->exec ("select fk_books, mediatype, filetype, fk_filetypes, fk_compressions, fk_encodings, " . + "edition, filename, filesize, filemtime " . + "from files " . + "left join filetypes on files.fk_filetypes = filetypes.pk " . + "where fk_books is not null and obsoleted = 0 and diskstatus = 0 " . + "order by fk_books, filename;"); + + +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("fk_books", SQLINT); + $filename = $db->get ("filename", SQLCHAR); + $filesize = $db->get ("filesize", SQLINT); + $filetype = $db->get ("filetype", SQLCHAR); + $fk_filetypes = $db->get ("fk_filetypes", SQLCHAR); + $filemtime = $db->get ("filemtime", SQLDATE); + $mediatype = $db->get ("mediatype", SQLCHAR); + $fk_encodings = $db->get ("fk_encodings", SQLCHAR); + $fk_compressions = $db->get ("fk_compressions", SQLCHAR); + + if (!strncmp ($filename, "cache/", 6)) { + $filename = "&f;$filename"; + } else { + $filename = "&f;dirs/$filename"; + } + + $mtime = date ("Y-m-d", $filemtime); + + if (!empty ($fk_encodings) && !strncmp ($mediatype, "text/", 5)) { + $mediatype .= "; charset=\"$fk_encodings\""; + } + if (empty ($mediatype)) { + $mediatype = "application/octet-stream"; + if (!empty ($fk_filetypes)) { + $mediatype .= "; type=\"$filetype ($fk_filetypes)\""; + } + } + $compression = ""; + if ($fk_compressions == "zip") { + $compression = "\n application/zip"; + } + + $s = " + + $mediatype$compression + $filesize + $mtime + + +"; + fputs ($fp, $s); + + } while ($db->NextRow ()); +} + +fputs ($fp, "\n\n"); + +fclose ($fp); + +_log (" Done!\n"); + +?> \ No newline at end of file diff --git a/catalog/admin/make-topten.php b/catalog/admin/make-topten.php new file mode 100644 index 0000000..607e26c --- /dev/null +++ b/catalog/admin/make-topten.php @@ -0,0 +1,263 @@ +page_encoding = \"UTF-8\"; + pageheader (\"$title\"); +?>\n\n"; +} + +$dir = "browse"; +$dir_scores = "$dir/scores"; + +@mkdir ("$config->documentroot/$dir", 0755); +@mkdir ("$config->documentroot/$dir_scores", 0755); + +$db = $config->db (); +$db2 = $config->db (); + +//////////////////////////////////////////////////////////////////////////////// +// top scores + +// disqualified because they are mp3 files and have "House" in title +// its amazing how many kids try to download these +// moreover "Usher" seems to be a rap artist +$disqualifiedbooks = "0, 6550, 6557, 9280, 9695, 9714"; +// unknown, anonymous and various +$disqualifiedauthors = "49, 116, 216"; + +function downloads ($where = "") { + global $db2, $config, $disqualifiedbooks; + $s = ""; + + $db2->exec (" +SELECT SUM (downloads) AS downloads +FROM dl +WHERE $where"); + + if ($db2->FirstRow ()) { + return $db2->get ("downloads", SQLINT); + } + + return 0; +} + +function topbooks ($num, $where = "") { + global $db2, $config, $disqualifiedbooks; + $s = ""; + + $db2->exec (" +SELECT fk_books, SUM (downloads) AS downloads +FROM dl +WHERE $where +GROUP BY fk_books +ORDER BY downloads DESC LIMIT $num"); + + $s .= "
    \n"; + + if ($db2->FirstRow ()) { + do { + $fk_books = $db2->get ("fk_books", SQLINT); + $downloads = $db2->get ("downloads", SQLINT); + $friendlytitle = friendlytitle ($fk_books, 100); + $s .= "
  1. etext/$fk_books\">$friendlytitle ($downloads)
  2. \n"; + } while ($db2->NextRow ()); + } + + $s .= "
\n"; + return $s; +} + +function topauthors ($num, $where = "") { + global $db2, $config, $disqualifiedbooks, $disqualifiedauthors; + $s = ""; + + $db2->exec (" +SELECT author, fk_authors, SUM (dl.downloads) as downloads +FROM authors, mn_books_authors, dl +WHERE $where + AND authors.pk = mn_books_authors.fk_authors + AND mn_books_authors.fk_books = dl.fk_books + AND fk_authors NOT IN ($disqualifiedauthors) +GROUP BY author, fk_authors +ORDER BY downloads DESC LIMIT $num"); + + $s .= "
    \n"; + + if ($db2->FirstRow ()) { + do { + $author = $db2->get ("author", SQLCHAR); + $fk_authors = $db2->get ("fk_authors", SQLINT); + $downloads = $db2->get ("downloads", SQLINT); + $href = find_browse_page ($author) . "#a$fk_authors"; + + $s .= ("
  1. $author ($downloads)
  2. \n"); + } while ($db2->NextRow ()); + } + + $s .= "
\n"; + return $s; +} + +///////////////////////////////////////////////////////////////////////////////////// +// start main + +echo ("creating temp table ..."); + +$db2->exec ("CREATE TEMP TABLE dl AS +SELECT scores.book_downloads.fk_books, scores.book_downloads.date, + scores.book_downloads.downloads, fk_langs +FROM scores.book_downloads, mn_books_langs +WHERE scores.book_downloads.fk_books = mn_books_langs.fk_books +AND scores.book_downloads.fk_books NOT IN ($disqualifiedbooks)"); + +echo (" done.\n"); + +$langs = array (); + +$langs[] = array ("", 100); // Top 100 all languages +$langs[] = array ("", 1000); // Top 1000 all languages + +$db2->exec ("select fk_langs, count (fk_langs) as cnt from mn_books_langs group by fk_langs order by cnt desc;"); +if ($db2->FirstRow ()) { + do { + $fk_langs = $db2->get ("fk_langs", SQLCHAR); + $langs[] = array ($fk_langs, 100); // Top 100 this language + } while ($db2->NextRow ()); +} + +echo (" done.\n"); + +$db2->exec ("select max (date) as latest, min (date) as earliest from scores.book_downloads"); +$latest = date ("Y-m-d", $db2->get ("latest", SQLDATE)); +$earliest = date ("Y-m-d", $db2->get ("earliest", SQLDATE)); + +// start output + +foreach ($langs as $l) { + $lang = $l[0]; + $num = $l[1]; + + $filesuffix = ""; + $titlesuffix = "$num"; + $langwhere = ""; + + if ($num != 100) { + $filesuffix .= "$num"; + } + + if (!empty ($lang)) { + $filesuffix .= "-$lang"; + $titlesuffix .= " ($lang)"; + $langwhere = "fk_langs = '$lang' AND "; + } + + if ($hd = fopen ($file = "$config->documentroot/$dir_scores/top$filesuffix.php", "w")) { + echo ("writing $file ... downloads ...\n"); + + $d1 = downloads ("$langwhere date >= current_date - interval '1 days'"); + $d7 = downloads ("$langwhere date >= current_date - interval '7 days'"); + $d30 = downloads ("$langwhere date >= current_date - interval '30 days'"); + + fputs ($hd, mk_header ("Top $titlesuffix")); + + $s = <<< EOF +

To determine the ranking we count the times each file gets downloaded. +Both HTTP and FTP transfers are counted. +Only transfers from ibiblio.org are counted as we have no access to our mirrors log files. +Multiple downloads from the same IP address on the same day count as one download. +IP addresses that download more than 100 files a day are considered +robots and are not considered. +Books made out of multiple files like most audio books are counted +if any file is downloaded.

+ + + + + + +
Downloaded Books
$latest$d1
last 7 days$d7
last 30 days$d30
+ +Pretty Pictures + +EOF; + + fputs ($hd, $s); + + $links = "

+ Top $num EBooks yesterday — + Top $num Authors yesterday — + Top $num EBooks last 7 days — + Top $num Authors last 7 days — + Top $num EBooks last 30 days — + Top $num Authors last 30 days +

+ +"; + + // Yesterday + + echo (" yesterday ... books ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num EBooks yesterday

\n\n"); + + fputs ($hd, topbooks ($num, "$langwhere date >= current_date - interval '1 days'")); + + echo (" authors ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num Authors yesterday

\n\n"); + + fputs ($hd, topauthors ($num, "$langwhere date >= current_date - interval '1 days'")); + + // Last 7 days + + echo (" last 7 days ... books ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num EBooks last 7 days

\n\n"); + + fputs ($hd, topbooks ($num, "$langwhere date >= current_date - interval '7 days'")); + + echo (" authors ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num Authors last 7 days

\n\n"); + + fputs ($hd, topauthors ($num, "$langwhere date >= current_date - interval '7 days'")); + + // Last 30 days + + echo (" last 30 days ... books ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num EBooks last 30 days

\n\n"); + + fputs ($hd, topbooks ($num, "$langwhere date >= current_date - interval '30 days'")); + + echo (" authors ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num Authors last 30 days

\n\n"); + + fputs ($hd, topauthors ($num, "$langwhere date >= current_date - interval '30 days'")); + + fputs ($hd, $links); + + fputs ($hd, "\n"); + fclose ($hd); + + echo (" done.\n"); + } +} + +?> diff --git a/catalog/admin/make-topten.php~ b/catalog/admin/make-topten.php~ new file mode 100644 index 0000000..73e7f2f --- /dev/null +++ b/catalog/admin/make-topten.php~ @@ -0,0 +1,262 @@ +page_encoding = \"UTF-8\"; + pageheader (\"$title\"); +?>\n\n"; +} + +$dir = "browse"; +$dir_scores = "$dir/scores"; + +@mkdir ("$config->documentroot/$dir", 0755); +@mkdir ("$config->documentroot/$dir_scores", 0755); + +$db = $config->db (); +$db2 = $config->db (); + +//////////////////////////////////////////////////////////////////////////////// +// top scores + +// disqualified because they are mp3 files and have "House" in title +// its amazing how many kids try to download these +// moreover "Usher" seems to be a rap artist +$disqualifiedbooks = "0, 6550, 6557, 9280, 9695, 9714"; +// unknown, anonymous and various +$disqualifiedauthors = "49, 116, 216"; + +function downloads ($where = "") { + global $db2, $config, $disqualifiedbooks; + $s = ""; + + $db2->exec (" +SELECT SUM (downloads) AS downloads +FROM dl +WHERE $where"); + + if ($db2->FirstRow ()) { + return $db2->get ("downloads", SQLINT); + } + + return 0; +} + +function topbooks ($num, $where = "") { + global $db2, $config, $disqualifiedbooks; + $s = ""; + + $db2->exec (" +SELECT fk_books, SUM (downloads) AS downloads +FROM dl +WHERE $where +GROUP BY fk_books +ORDER BY downloads DESC LIMIT $num"); + + $s .= "
    \n"; + + if ($db2->FirstRow ()) { + do { + $fk_books = $db2->get ("fk_books", SQLINT); + $downloads = $db2->get ("downloads", SQLINT); + $friendlytitle = friendlytitle ($fk_books, 100); + $s .= "
  1. etext/$fk_books\">$friendlytitle ($downloads)
  2. \n"; + } while ($db2->NextRow ()); + } + + $s .= "
\n"; + return $s; +} + +function topauthors ($num, $where = "") { + global $db2, $config, $disqualifiedbooks, $disqualifiedauthors; + $s = ""; + + $db2->exec (" +SELECT author, fk_authors, SUM (dl.downloads) as downloads +FROM authors, mn_books_authors, dl +WHERE $where + AND authors.pk = mn_books_authors.fk_authors + AND mn_books_authors.fk_books = dl.fk_books + AND fk_authors NOT IN ($disqualifiedauthors) +GROUP BY author, fk_authors +ORDER BY downloads DESC LIMIT $num"); + + $s .= "
    \n"; + + if ($db2->FirstRow ()) { + do { + $author = $db2->get ("author", SQLCHAR); + $fk_authors = $db2->get ("fk_authors", SQLINT); + $downloads = $db2->get ("downloads", SQLINT); + $href = find_browse_page ($author) . "#a$fk_authors"; + + $s .= ("
  1. $author ($downloads)
  2. \n"); + } while ($db2->NextRow ()); + } + + $s .= "
\n"; + return $s; +} + +///////////////////////////////////////////////////////////////////////////////////// +// start main + +echo ("creating temp table ..."); + +$db2->exec ("CREATE TEMP TABLE dl AS +SELECT scores.book_downloads.fk_books, scores.book_downloads.date, + scores.book_downloads.downloads, fk_langs +FROM scores.book_downloads, mn_books_langs +WHERE scores.book_downloads.fk_books = mn_books_langs.fk_books +AND scores.book_downloads.fk_books NOT IN ($disqualifiedbooks)"); + +echo (" done.\n"); + +$langs = array (); + +$langs[] = array ("", 100); // Top 100 all languages +$langs[] = array ("", 1000); // Top 1000 all languages + +$db2->exec ("select fk_langs, count (fk_langs) as cnt from mn_books_langs group by fk_langs order by cnt desc;"); +if ($db2->FirstRow ()) { + do { + $fk_langs = $db2->get ("fk_langs", SQLCHAR); + $langs[] = array ($fk_langs, 100); // Top 100 this language + } while ($db2->NextRow ()); +} + +echo (" done.\n"); + +$db2->exec ("select max (date) as latest, min (date) as earliest from scores.book_downloads"); +$latest = date ("Y-m-d", $db2->get ("latest", SQLDATE)); +$earliest = date ("Y-m-d", $db2->get ("earliest", SQLDATE)); + +// start output + +foreach ($langs as $l) { + $lang = $l[0]; + $num = $l[1]; + + $filesuffix = ""; + $titlesuffix = "$num"; + $langwhere = ""; + + if ($num != 100) { + $filesuffix .= "$num"; + } + + if (!empty ($lang)) { + $filesuffix .= "-$lang"; + $titlesuffix .= " ($lang)"; + $langwhere = "fk_langs = '$lang' AND "; + } + + if ($hd = fopen ($file = "$config->documentroot/$dir_scores/top$filesuffix.php", "w")) { + echo ("writing $file ... downloads ...\n"); + + $d1 = downloads ("$langwhere date >= current_date - interval '1 days'"); + $d7 = downloads ("$langwhere date >= current_date - interval '7 days'"); + $d30 = downloads ("$langwhere date >= current_date - interval '30 days'"); + + fputs ($hd, mk_header ("Top $titlesuffix")); + + $s = <<< EOF +

To determine the ranking we count the times each file gets downloaded. +Both HTTP and FTP transfers are counted. +Only transfers from ibiblio.org are counted as we have no access to our mirrors log files. +Multiple downloads from the same IP address on the same day count as one download. +IP addresses that download more than 100 files a day are considered +robots and are not considered. +Books made out of multiple files like most audio books are counted +if any file is downloaded.

+ + + + + + +
Downloaded Books
$latest$d1
last 7 days$d7
last 30 days$d30
+ +Pretty Pictures + +EOF; + + fputs ($hd, $s); + + $links = "

+ Top $num EBooks yesterday — + Top $num Authors yesterday — + Top $num EBooks last 7 days — + Top $num Authors last 7 days — + Top $num EBooks last 30 days — + Top $num Authors last 30 days +

+ +"; + + // Yesterday + + echo (" yesterday ... books ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num EBooks yesterday

\n\n"); + + fputs ($hd, topbooks ($num, "$langwhere date >= current_date - interval '1 days'")); + + echo (" authors ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num Authors yesterday

\n\n"); + + fputs ($hd, topauthors ($num, "$langwhere date >= current_date - interval '1 days'")); + + // Last 7 days + + echo (" last 7 days ... books ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num EBooks last 7 days

\n\n"); + + fputs ($hd, topbooks ($num, "$langwhere date >= current_date - interval '7 days'")); + + echo (" authors ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num Authors last 7 days

\n\n"); + + fputs ($hd, topauthors ($num, "$langwhere date >= current_date - interval '7 days'")); + + // Last 30 days + + echo (" last 30 days ... books ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num EBooks last 30 days

\n\n"); + + fputs ($hd, topbooks ($num, "$langwhere date >= current_date - interval '30 days'")); + + echo (" authors ..."); + + fputs ($hd, $links); + fputs ($hd, "

Top $num Authors last 30 days

\n\n"); + + fputs ($hd, topauthors ($num, "$langwhere date >= current_date - interval '30 days'")); + + fputs ($hd, $links); + + fputs ($hd, "\n"); + fclose ($hd); + + echo (" done.\n"); + } +} + +?> diff --git a/catalog/admin/mirror.php b/catalog/admin/mirror.php new file mode 100644 index 0000000..4c22e80 --- /dev/null +++ b/catalog/admin/mirror.php @@ -0,0 +1,77 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); +getstr ("fk_mirrors"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this mirror."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("continent", "continent", "Continent", SQLCHAR, 80, 80, false); + $f->Text ("nation", "nation", "Nation", SQLCHAR, 80, 80, false); + $f->Text ("location", "location", "Location", SQLCHAR, 80, 80, false); + $f->Text ("provider", "provider", "Provider", SQLCHAR, 80, 240, true); + $f->Text ("url", "url", "URL", SQLCHAR, 80, 240, true); + $f->TextArea ("note", "note", "Note", SQLCHAR, 4, 80, false); + + $f->LoadData ("select * from mirrors where pk = '$fk_mirrors'"); +} +$f->Hidden ("fk_mirrors"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into mirrors " . $sql)) { + msg ("Mirror added !"); + } else { + error_msg ("Could not add mirror!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update mirrors set " . $sql . "where pk = '$fk_mirrors'")) { + msg ("Mirror modified !"); + } else { + error_msg ("Could not modify mirror !"); + } + } +} +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mirrors where pk = '$fk_mirrors'")) { + msg ("Mirror deleted !"); + } else { + error_msg ("Could not delete mirror !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + p ("" . + "Back to Mirror"); + } +} else { + $f->Output ($caption, $caption); +} + +p ("Back to Mirror List"); + +pagefooter (); + +?> diff --git a/catalog/admin/mirror.php~ b/catalog/admin/mirror.php~ new file mode 100644 index 0000000..1088f6e --- /dev/null +++ b/catalog/admin/mirror.php~ @@ -0,0 +1,76 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); +getstr ("fk_mirrors"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this mirror."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("continent", "continent", "Continent", SQLCHAR, 80, 80, false); + $f->Text ("nation", "nation", "Nation", SQLCHAR, 80, 80, false); + $f->Text ("location", "location", "Location", SQLCHAR, 80, 80, false); + $f->Text ("provider", "provider", "Provider", SQLCHAR, 80, 240, true); + $f->Text ("url", "url", "URL", SQLCHAR, 80, 240, true); + $f->TextArea ("note", "note", "Note", SQLCHAR, 4, 80, false); + + $f->LoadData ("select * from mirrors where pk = '$fk_mirrors'"); +} +$f->Hidden ("fk_mirrors"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into mirrors " . $sql)) { + msg ("Mirror added !"); + } else { + error_msg ("Could not add mirror!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update mirrors set " . $sql . "where pk = '$fk_mirrors'")) { + msg ("Mirror modified !"); + } else { + error_msg ("Could not modify mirror !"); + } + } +} +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mirrors where pk = '$fk_mirrors'")) { + msg ("Mirror deleted !"); + } else { + error_msg ("Could not delete mirror !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + p ("" . + "Back to Mirror"); + } +} else { + $f->Output ($caption, $caption); +} + +p ("Back to Mirror List"); + +pagefooter (); + +?> diff --git a/catalog/admin/mirrors_list.php b/catalog/admin/mirrors_list.php new file mode 100644 index 0000000..ecc2a7d --- /dev/null +++ b/catalog/admin/mirrors_list.php @@ -0,0 +1,33 @@ +AddColumn ("$prefix=edit&fk_mirrors=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_mirrors=#pk#\">Delete", "", "narrow"); + // $this->AddSimpleColumn ("continent", "Continent"); + $this->AddSimpleColumn ("nation", "Nation"); + $this->AddSimpleColumn ("location", "Location"); + $this->AddSimpleColumn ("provider", "Provider"); + $this->AddSimpleColumn ("url", "URL"); + $this->AddSimpleColumn ("note", "Note"); + } +} + +$db = $config->db (); + +$db->exec ("select * from mirrors order by nation, location, provider;"); +$table = new ListMirrorsTable (); +$table->PrintTable ($db, $caption); + +pagefooter (); + +?> diff --git a/catalog/admin/mirrors_list.php~ b/catalog/admin/mirrors_list.php~ new file mode 100644 index 0000000..92ef326 --- /dev/null +++ b/catalog/admin/mirrors_list.php~ @@ -0,0 +1,32 @@ +AddColumn ("$prefix=edit&fk_mirrors=#pk#\">Edit", + "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_mirrors=#pk#\">Delete", "", "narrow"); + // $this->AddSimpleColumn ("continent", "Continent"); + $this->AddSimpleColumn ("nation", "Nation"); + $this->AddSimpleColumn ("location", "Location"); + $this->AddSimpleColumn ("provider", "Provider"); + $this->AddSimpleColumn ("url", "URL"); + $this->AddSimpleColumn ("note", "Note"); + } +} + +$db = $config->db (); + +$db->exec ("select * from mirrors order by nation, location, provider;"); +$table = new ListMirrorsTable (); +$table->PrintTable ($db, $caption); + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_authors.php b/catalog/admin/mn_books_authors.php new file mode 100644 index 0000000..0ae4122 --- /dev/null +++ b/catalog/admin/mn_books_authors.php @@ -0,0 +1,80 @@ +db (); +$db->logger = new logger (); + +getint ("fk_books"); +getint ("fk_authors"); +getstr ("fk_roles"); +getint ("heading"); +$sql_fk_roles = $db->f ($fk_roles, SQLCHAR); + +$caption = MNCaption ("Author", "Book"); + +$f->KeySelect ("fk_roles", "fk_roles", "Author Role", SQLCHAR, 40, 40, true); +$f->last->LoadSQL ("select pk as key, role as caption from roles order by role"); +$f->last->DefValue ("cr"); +$f->last->ToolTip ("In which role did this author contribute to the book?"); + +$f->KeySelect ("heading", "heading", "Heading", SQLINT, 10, 2, true); +$f->last->PushOptions ($titles_heading); +$f->last->DefValue (1); +$f->last->ToolTip ("Should this author generate a user-visible heading?"); + +$f->LoadData ("select * from mn_books_authors " . + "where fk_books = $fk_books and fk_authors = $fk_authors and fk_roles = $sql_fk_roles"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to unlink this book author. " . + "Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} + +$f->Hidden ("fk_books"); +$f->Hidden ("fk_authors"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + if ($db->Exec ("insert into mn_books_authors (fk_books, fk_authors, fk_roles, heading) " . + "values ($fk_books, $fk_authors, $sql_fk_roles, $heading)")) { + $msg = "msg=Book author linked !"; + } else { + $msg = "errormsg=Could not link book author !"; + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + if ($db->Exec ("update mn_books_authors " . + "set fk_roles = $sql_fk_roles, heading = $heading " . + "where fk_books = $fk_books and fk_authors = $fk_authors")) { + $msg = "msg=Author link modified !"; + } else { + $msg = "errormsg=Could not modify author link !"; + } + } +} +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_authors " . + "where fk_books = $fk_books and fk_authors = $fk_authors and fk_roles = $sql_fk_roles")) { + $msg = "msg=Book author unlinked !"; + } else { + $msg = "errormsg=Could not unlink book author !"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption); +$f->Output ($caption, $caption); +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_authors.php~ b/catalog/admin/mn_books_authors.php~ new file mode 100644 index 0000000..e226edc --- /dev/null +++ b/catalog/admin/mn_books_authors.php~ @@ -0,0 +1,75 @@ +f ($fk_roles, SQLCHAR); + +$caption = MNCaption ("Author", "Book"); + +$f->KeySelect ("fk_roles", "fk_roles", "Author Role", SQLCHAR, 40, 40, true); +$f->last->LoadSQL ("select pk as key, role as caption from roles order by role"); +$f->last->DefValue ("cr"); +$f->last->ToolTip ("In which role did this author contribute to the book?"); + +$f->KeySelect ("heading", "heading", "Heading", SQLINT, 10, 2, true); +$f->last->PushOptions ($titles_heading); +$f->last->DefValue (1); +$f->last->ToolTip ("Should this author generate a user-visible heading?"); + +$f->LoadData ("select * from mn_books_authors " . + "where fk_books = $fk_books and fk_authors = $fk_authors and fk_roles = $sql_fk_roles"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to unlink this book author. " . + "Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} + +$f->Hidden ("fk_books"); +$f->Hidden ("fk_authors"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + if ($db->Exec ("insert into mn_books_authors (fk_books, fk_authors, fk_roles, heading) " . + "values ($fk_books, $fk_authors, $sql_fk_roles, $heading)")) { + $msg = "msg=Book author linked !"; + } else { + $msg = "errormsg=Could not link book author !"; + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + if ($db->Exec ("update mn_books_authors " . + "set fk_roles = $sql_fk_roles, heading = $heading " . + "where fk_books = $fk_books and fk_authors = $fk_authors")) { + $msg = "msg=Author link modified !"; + } else { + $msg = "errormsg=Could not modify author link !"; + } + } +} +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_authors " . + "where fk_books = $fk_books and fk_authors = $fk_authors and fk_roles = $sql_fk_roles")) { + $msg = "msg=Book author unlinked !"; + } else { + $msg = "errormsg=Could not unlink book author !"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption); +$f->Output ($caption, $caption); +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_authors_list.php b/catalog/admin/mn_books_authors_list.php new file mode 100644 index 0000000..8663e19 --- /dev/null +++ b/catalog/admin/mn_books_authors_list.php @@ -0,0 +1,50 @@ +db (); +$db->logger = new logger (); + +pageheader ($caption = MNCaption ("Author", "Book")); + +getint ("fk_books"); + +class ListAuthorsTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddColumn ("Link", "", null, "1%"); + $this->AddSimpleColumn ("author", "Name"); + $this->AddSimpleColumn ("born_floor", "Born", "narrow right"); + $this->AddSimpleColumn ("died_floor", "Died", "narrow right"); + } +} + +echo (" +

Please enter the first few characters of the authors name (at least one). +Use * as wildcard.

+ +
+ +"); +form_relay ("mode"); +form_relay ("fk_books"); +form_submit ("Search"); +echo ("
\n"); + +if ($filter != "") { + $filter = str_replace ('*', '%', $filter); + $sql_filter = $db->f ("$filter%", SQLCHAR); + $db->exec ("select * from authors where author ilike $sql_filter order by author;"); + $table = new ListAuthorsTable (); + $table->PrintTable ($db, $caption); +} + +p ("Add Author"); + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_authors_list.php~ b/catalog/admin/mn_books_authors_list.php~ new file mode 100644 index 0000000..52b633c --- /dev/null +++ b/catalog/admin/mn_books_authors_list.php~ @@ -0,0 +1,45 @@ +AddColumn ("Link", "", null, "1%"); + $this->AddSimpleColumn ("author", "Name"); + $this->AddSimpleColumn ("born_floor", "Born", "narrow right"); + $this->AddSimpleColumn ("died_floor", "Died", "narrow right"); + } +} + +echo (" +

Please enter the first few characters of the authors name (at least one). +Use * as wildcard.

+ +
+ +"); +form_relay ("mode"); +form_relay ("fk_books"); +form_submit ("Search"); +echo ("
\n"); + +if ($filter != "") { + $filter = str_replace ('*', '%', $filter); + $sql_filter = $db->f ("$filter%", SQLCHAR); + $db->exec ("select * from authors where author ilike $sql_filter order by author;"); + $table = new ListAuthorsTable (); + $table->PrintTable ($db, $caption); +} + +p ("Add Author"); + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_categories.php b/catalog/admin/mn_books_categories.php new file mode 100644 index 0000000..6ace4f9 --- /dev/null +++ b/catalog/admin/mn_books_categories.php @@ -0,0 +1,65 @@ +db (); +$db->logger = new logger (); + +getint ("fk_books"); +getint ("fk_categories"); + +if (isupdatemode ("add")) { + if ($db->Exec ("insert into mn_books_categories (fk_books, fk_categories) " . + "values ($fk_books, '$fk_categories')")) { + $msg = "msg=Book Category linked !"; + } else { + $msg = "errormsg=Could not link book Category !"; + } +} + +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_categories " . + "where fk_books = $fk_books and fk_categories = '$fk_categories'")) { + $msg = "msg=Book Category unlinked !"; + } else { + $msg = "errormsg=Could not unlink book Category !"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption = MNCaption ("Category", "Book")); + +class ListCategoriesTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddColumn ("Link", "", null, "1%"); + $this->AddSimpleColumn ("category", "Category"); + } +} + +if (isfirstmode ("add")) { + $db->exec ("select * from categories order by category;"); + $table = new ListCategoriesTable (); + $table->PrintTable ($db, $caption); +} + +if (isfirstmode ("delete")) { + $f->Hidden ("fk_books"); + $f->Hidden ("fk_categories"); + $f->SubCaption ("You are about to unlink this book Category."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_categories.php~ b/catalog/admin/mn_books_categories.php~ new file mode 100644 index 0000000..d817447 --- /dev/null +++ b/catalog/admin/mn_books_categories.php~ @@ -0,0 +1,60 @@ +Exec ("insert into mn_books_categories (fk_books, fk_categories) " . + "values ($fk_books, '$fk_categories')")) { + $msg = "msg=Book Category linked !"; + } else { + $msg = "errormsg=Could not link book Category !"; + } +} + +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_categories " . + "where fk_books = $fk_books and fk_categories = '$fk_categories'")) { + $msg = "msg=Book Category unlinked !"; + } else { + $msg = "errormsg=Could not unlink book Category !"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption = MNCaption ("Category", "Book")); + +class ListCategoriesTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddColumn ("Link", "", null, "1%"); + $this->AddSimpleColumn ("category", "Category"); + } +} + +if (isfirstmode ("add")) { + $db->exec ("select * from categories order by category;"); + $table = new ListCategoriesTable (); + $table->PrintTable ($db, $caption); +} + +if (isfirstmode ("delete")) { + $f->Hidden ("fk_books"); + $f->Hidden ("fk_categories"); + $f->SubCaption ("You are about to unlink this book Category."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_langs.php b/catalog/admin/mn_books_langs.php new file mode 100644 index 0000000..cfbd1da --- /dev/null +++ b/catalog/admin/mn_books_langs.php @@ -0,0 +1,79 @@ +db (); +$db->logger = new logger (); + +getint ("fk_books"); +getstr ("fk_langs"); + +if (isupdatemode ("add")) { + if ($db->Exec ("insert into mn_books_langs (fk_books, fk_langs) " . + "values ($fk_books, '$fk_langs')")) { + $msg = "msg=Book language linked !"; + } else { + $msg = "errormsg=Could not link book language !"; + } +} + +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_langs " . + "where fk_books = $fk_books and fk_langs = '$fk_langs'")) { + $msg = "msg=Book language unlinked !"; + } else { + $msg = "errormsg=Could not unlink book language !"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption = MNCaption ("Language", "Book")); + +class ListLangsTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddColumn ("Link", "", null, "1%"); + $this->AddSimpleColumn ("lang", "Language"); + } +} + +if (isfirstmode ("add")) { + $f->OutputFormHeader (); + echo ("

Please enter the first few characters of " . + "the language name (at least one). Use * as wildcard.

\n" . + " \n"); + form_submit ("Search"); + + form_relay ("mode"); + form_relay ("fk_books"); + form_relay ("fk_langs"); + form_close (); + + if ($filter != "") { + $filter = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from langs where lang like '$filter%' order by lang;"); + $table = new ListLangsTable (); + $table->PrintTable ($db, $caption); + } +} + +if (isfirstmode ("delete")) { + $f->Hidden ("fk_books"); + $f->Hidden ("fk_langs"); + $f->SubCaption ("You are about to unlink this book language."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_langs.php~ b/catalog/admin/mn_books_langs.php~ new file mode 100644 index 0000000..7938f71 --- /dev/null +++ b/catalog/admin/mn_books_langs.php~ @@ -0,0 +1,74 @@ +Exec ("insert into mn_books_langs (fk_books, fk_langs) " . + "values ($fk_books, '$fk_langs')")) { + $msg = "msg=Book language linked !"; + } else { + $msg = "errormsg=Could not link book language !"; + } +} + +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_langs " . + "where fk_books = $fk_books and fk_langs = '$fk_langs'")) { + $msg = "msg=Book language unlinked !"; + } else { + $msg = "errormsg=Could not unlink book language !"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption = MNCaption ("Language", "Book")); + +class ListLangsTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddColumn ("Link", "", null, "1%"); + $this->AddSimpleColumn ("lang", "Language"); + } +} + +if (isfirstmode ("add")) { + $f->OutputFormHeader (); + echo ("

Please enter the first few characters of " . + "the language name (at least one). Use * as wildcard.

\n" . + " \n"); + form_submit ("Search"); + + form_relay ("mode"); + form_relay ("fk_books"); + form_relay ("fk_langs"); + form_close (); + + if ($filter != "") { + $filter = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from langs where lang like '$filter%' order by lang;"); + $table = new ListLangsTable (); + $table->PrintTable ($db, $caption); + } +} + +if (isfirstmode ("delete")) { + $f->Hidden ("fk_books"); + $f->Hidden ("fk_langs"); + $f->SubCaption ("You are about to unlink this book language."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_loccs.php b/catalog/admin/mn_books_loccs.php new file mode 100644 index 0000000..3b4cd79 --- /dev/null +++ b/catalog/admin/mn_books_loccs.php @@ -0,0 +1,92 @@ +db (); +$db->logger = new logger (); + +getint ("fk_books"); +getstr ("fk_loccs"); + +$locc_name = "Unknown"; +if ($db->Exec("select locc from loccs where pk = '$fk_loccs'")) { +#it will make life nicer if the message includes *what* LoC was linked. + $locc_name = $db->Get("locc"); + } + +if (isupdatemode ("add")) { + if ($db->Exec ("insert into mn_books_loccs (fk_books, fk_loccs) " . + "values ($fk_books, '$fk_loccs')")) { + $msg = "msg=LoCC '$fk_loccs : $locc_name' linked!"; + } else { + $msg = "errormsg=Could not link LoCC '$fk_loccs : $locc_name'!"; + } +} + +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_loccs " . + "where fk_books = $fk_books and fk_loccs = '$fk_loccs'")) { + $msg = "msg=LoCC '$fk_loccs : $locc_name' unlinked!"; + } else { + $msg = "errormsg=Could not unlink LoCC '$fk_loccs : $locc_name'!"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +$db->Exec("select text from attributes where fk_books = $fk_books " . + "and fk_attriblist=245"); +$book_name=$db->Get("text"); + +pageheader ($caption = MNCaption ("LoC Class", "'$book_name'")); + +class ListLoccsTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddColumn ("Link", "", null, "1%"); + $this->AddColumn("#pk#", "Code", "narrow"); + $this->AddSimpleColumn ("locc", "LoC Class"); + } +} + +if (isfirstmode ("add")) { + $f->OutputFormHeader (); + echo ("

Please enter the first few characters of " . + "the LoC class description (at least one). Use * as wildcard.

\n" . + " \n"); + form_submit ("Search"); + + form_relay ("mode"); + form_relay ("fk_books"); + form_relay ("fk_loccs"); + form_close (); + + if ($filter != "") { + $filter = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from loccs where locc like '$filter%' order by locc;"); + $table = new ListLoccsTable (); + $table->PrintTable ($db, $caption); + } +} + +if (isfirstmode ("delete")) { + + $f->Hidden ("fk_books"); + $f->Hidden ("fk_loccs"); + $f->SubCaption ("You are about to unlink LoCC '$fk_loccs : $locc_name' from " . + "'$book_name'."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_loccs.php~ b/catalog/admin/mn_books_loccs.php~ new file mode 100644 index 0000000..faff2b0 --- /dev/null +++ b/catalog/admin/mn_books_loccs.php~ @@ -0,0 +1,87 @@ +Exec("select locc from loccs where pk = '$fk_loccs'")) { +#it will make life nicer if the message includes *what* LoC was linked. + $locc_name = $db->Get("locc"); + } + +if (isupdatemode ("add")) { + if ($db->Exec ("insert into mn_books_loccs (fk_books, fk_loccs) " . + "values ($fk_books, '$fk_loccs')")) { + $msg = "msg=LoCC '$fk_loccs : $locc_name' linked!"; + } else { + $msg = "errormsg=Could not link LoCC '$fk_loccs : $locc_name'!"; + } +} + +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_loccs " . + "where fk_books = $fk_books and fk_loccs = '$fk_loccs'")) { + $msg = "msg=LoCC '$fk_loccs : $locc_name' unlinked!"; + } else { + $msg = "errormsg=Could not unlink LoCC '$fk_loccs : $locc_name'!"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +$db->Exec("select text from attributes where fk_books = $fk_books " . + "and fk_attriblist=245"); +$book_name=$db->Get("text"); + +pageheader ($caption = MNCaption ("LoC Class", "'$book_name'")); + +class ListLoccsTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddColumn ("Link", "", null, "1%"); + $this->AddColumn("#pk#", "Code", "narrow"); + $this->AddSimpleColumn ("locc", "LoC Class"); + } +} + +if (isfirstmode ("add")) { + $f->OutputFormHeader (); + echo ("

Please enter the first few characters of " . + "the LoC class description (at least one). Use * as wildcard.

\n" . + " \n"); + form_submit ("Search"); + + form_relay ("mode"); + form_relay ("fk_books"); + form_relay ("fk_loccs"); + form_close (); + + if ($filter != "") { + $filter = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from loccs where locc like '$filter%' order by locc;"); + $table = new ListLoccsTable (); + $table->PrintTable ($db, $caption); + } +} + +if (isfirstmode ("delete")) { + + $f->Hidden ("fk_books"); + $f->Hidden ("fk_loccs"); + $f->SubCaption ("You are about to unlink LoCC '$fk_loccs : $locc_name' from " . + "'$book_name'."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_subjects.php b/catalog/admin/mn_books_subjects.php new file mode 100644 index 0000000..df7d565 --- /dev/null +++ b/catalog/admin/mn_books_subjects.php @@ -0,0 +1,93 @@ +db (); +$db->logger = new logger (); + +getint ("fk_books"); +getint ("fk_subjects"); + +$subject_name = ""; +if ($db->Exec("select subject from subjects where pk = $fk_subjects")) { +#it will make life nicer if the message includes *what* subject was linked. + $subject_name = $db->Get("subject"); + } +if (!$subject_name) { + /* if getting the actual name fails for some reason, use the internal number instead; + at least it is something...*/ + $subject_name = "Internal #: $fk_subjects"; + } +if (isupdatemode ("add")) { + if ($db->Exec ("insert into mn_books_subjects (fk_books, fk_subjects) " . + "values ($fk_books, '$fk_subjects')")) { + $msg = "msg=Subject '$subject_name' linked!"; + } else { + $msg = "errormsg=Could not link Subject '$subject_name'!"; + } +} + +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_subjects " . + "where fk_books = $fk_books and fk_subjects = '$fk_subjects'")) { + $msg = "msg=Subject '$subject_name' unlinked !"; + } else { + $msg = "errormsg=Could not unlink Subject '$subject_name'!"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption = MNCaption ("Subject", "Book")); + +class ListSubjectsTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddColumn ("Link", "Add", null, "1%"); + $this->AddColumn ("#subject#", "Subject"); + } +} + +if (isfirstmode ("add")) { + $f->OutputFormHeader (); + echo ("

Please enter the first few characters of " . + "the Subject description (at least one). Use * as wildcard.

\n" . + " \n"); + form_submit ("Search"); + + form_relay ("mode"); + form_relay ("fk_books"); + form_relay ("fk_subjects"); + form_close (); + + if ($filter != "") { + $filter = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from subjects where subject like '$filter%' order by subject;"); + $table = new ListSubjectsTable (); + $table->PrintTable ($db, $caption); + } +} + +if (isfirstmode ("delete")) { + $db->Exec("select text from attributes where fk_books = $fk_books " . + "and fk_attriblist=245"); + $book_name=$db->Get("text"); + $f->Hidden ("fk_books"); + $f->Hidden ("fk_subjects"); + $f->SubCaption ("You are about to unlink the Subject '$subject_name' " . + "from the book entitled '$book_name'."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/mn_books_subjects.php~ b/catalog/admin/mn_books_subjects.php~ new file mode 100644 index 0000000..d54f1da --- /dev/null +++ b/catalog/admin/mn_books_subjects.php~ @@ -0,0 +1,88 @@ +Exec("select subject from subjects where pk = $fk_subjects")) { +#it will make life nicer if the message includes *what* subject was linked. + $subject_name = $db->Get("subject"); + } +if (!$subject_name) { + /* if getting the actual name fails for some reason, use the internal number instead; + at least it is something...*/ + $subject_name = "Internal #: $fk_subjects"; + } +if (isupdatemode ("add")) { + if ($db->Exec ("insert into mn_books_subjects (fk_books, fk_subjects) " . + "values ($fk_books, '$fk_subjects')")) { + $msg = "msg=Subject '$subject_name' linked!"; + } else { + $msg = "errormsg=Could not link Subject '$subject_name'!"; + } +} + +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from mn_books_subjects " . + "where fk_books = $fk_books and fk_subjects = '$fk_subjects'")) { + $msg = "msg=Subject '$subject_name' unlinked !"; + } else { + $msg = "errormsg=Could not unlink Subject '$subject_name'!"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption = MNCaption ("Subject", "Book")); + +class ListSubjectsTable extends ListTable { + function __construct () { + global $fk_books; + $this->AddColumn ("Link", "Add", null, "1%"); + $this->AddColumn ("#subject#", "Subject"); + } +} + +if (isfirstmode ("add")) { + $f->OutputFormHeader (); + echo ("

Please enter the first few characters of " . + "the Subject description (at least one). Use * as wildcard.

\n" . + " \n"); + form_submit ("Search"); + + form_relay ("mode"); + form_relay ("fk_books"); + form_relay ("fk_subjects"); + form_close (); + + if ($filter != "") { + $filter = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from subjects where subject like '$filter%' order by subject;"); + $table = new ListSubjectsTable (); + $table->PrintTable ($db, $caption); + } +} + +if (isfirstmode ("delete")) { + $db->Exec("select text from attributes where fk_books = $fk_books " . + "and fk_attriblist=245"); + $book_name=$db->Get("text"); + $f->Hidden ("fk_books"); + $f->Hidden ("fk_subjects"); + $f->SubCaption ("You are about to unlink the Subject '$subject_name' " . + "from the book entitled '$book_name'."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); + $f->Output ($caption, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/password.php b/catalog/admin/password.php new file mode 100644 index 0000000..05e6e2c --- /dev/null +++ b/catalog/admin/password.php @@ -0,0 +1,82 @@ +db (); +$db->logger = new logger (); + +include_once ("sqlform.phh"); + +if ($admin) { + // changing other people's passwords requires createuser permission + authenticate ("createuser"); + getint ("fk_users"); + $db->exec ("select login from users where pk = $fk_users"); + if ($db->FirstRow ()) { + $login = $db->get ("login", SQLCHAR); + } else { + error_msg ("No such user"); + } + pageheader ("Administrator Change Password For: $login"); +} else { + authenticate (); + $login = $_SERVER['PHP_AUTH_USER']; + $sql_login = $db->f ($login, SQLCHAR); + $db->exec ("select pk from users where login = $sql_login"); + if ($db->FirstRow ()) { + $fk_users = $db->get ("pk", SQLINT); + } + pageheader ("Change Password For: $login"); +} + +getstr ("filter"); + +if (!isupdate ()) { + form_open (); + if ($admin) { + p ("Enter password for user {$_SERVER['PHP_AUTH_USER']}: "); + } else { + p ("Enter old password for user $login: "); + } + p ("Do not use the same password as for other important services!"); + p ("Enter new password for user $login: at least 8 characters"); + p ("Reenter new password for user $login: "); + form_hidden ("admin", $admin); + form_hidden ("fk_users", $fk_users); + form_hidden ("filter", $filter); + form_submit ("Change password"); + form_close (); +} else { + // make sure you got the old password + getstr ("oldpassword"); + $sql_login = $db->f ($_SERVER['PHP_AUTH_USER'], SQLCHAR); + $sql_password = $db->f (md5 ($oldpassword), SQLCHAR); + $db->exec ("select pk from users where login = $sql_login and password = $sql_password"); + if (!$db->FirstRow ()) { + error_msg ("Incorrect old password!"); + die (); + } + getstr ("newpassword1"); + getstr ("newpassword2"); + if ($newpassword1 != $newpassword2) { + error_msg ("You entered 2 different passwords!"); + } + if (strlen ($newpassword1) < 8) { + error_msg ("New password must be at least 8 characters long."); + } + $sql_password = $db->f (md5 ($newpassword1), SQLCHAR); + if ($db->exec ("update users set password = $sql_password where pk = $fk_users")) { + msg ("Password changed"); + } else { + error_msg ("Could not change password"); + } +} + +p ("Back to User"); +p ("Back to User List"); + +pagefooter (); + +?> diff --git a/catalog/admin/password.php~ b/catalog/admin/password.php~ new file mode 100644 index 0000000..12ef1f6 --- /dev/null +++ b/catalog/admin/password.php~ @@ -0,0 +1,81 @@ +db (); +$db->logger = new logger (); + +include_once ("sqlform.phh"); + +if ($admin) { + // changing other people's passwords requires createuser permission + authenticate ("createuser"); + getint ("fk_users"); + $db->exec ("select login from users where pk = $fk_users"); + if ($db->FirstRow ()) { + $login = $db->get ("login", SQLCHAR); + } else { + error_msg ("No such user"); + } + pageheader ("Administrator Change Password For: $login"); +} else { + authenticate (); + $login = $_SERVER['PHP_AUTH_USER']; + $sql_login = $db->f ($login, SQLCHAR); + $db->exec ("select pk from users where login = $sql_login"); + if ($db->FirstRow ()) { + $fk_users = $db->get ("pk", SQLINT); + } + pageheader ("Change Password For: $login"); +} + +getstr ("filter"); + +if (!isupdate ()) { + form_open (); + if ($admin) { + p ("Enter password for user {$_SERVER['PHP_AUTH_USER']}: "); + } else { + p ("Enter old password for user $login: "); + } + p ("Do not use the same password as for other important services!"); + p ("Enter new password for user $login: at least 8 characters"); + p ("Reenter new password for user $login: "); + form_hidden ("admin", $admin); + form_hidden ("fk_users", $fk_users); + form_hidden ("filter", $filter); + form_submit ("Change password"); + form_close (); +} else { + // make sure you got the old password + getstr ("oldpassword"); + $sql_login = $db->f ($_SERVER['PHP_AUTH_USER'], SQLCHAR); + $sql_password = $db->f (md5 ($oldpassword), SQLCHAR); + $db->exec ("select pk from users where login = $sql_login and password = $sql_password"); + if (!$db->FirstRow ()) { + error_msg ("Incorrect old password!"); + die (); + } + getstr ("newpassword1"); + getstr ("newpassword2"); + if ($newpassword1 != $newpassword2) { + error_msg ("You entered 2 different passwords!"); + } + if (strlen ($newpassword1) < 8) { + error_msg ("New password must be at least 8 characters long."); + } + $sql_password = $db->f (md5 ($newpassword1), SQLCHAR); + if ($db->exec ("update users set password = $sql_password where pk = $fk_users")) { + msg ("Password changed"); + } else { + error_msg ("Could not change password"); + } +} + +p ("Back to User"); +p ("Back to User List"); + +pagefooter (); + +?> diff --git a/catalog/admin/phpinfo.php~ b/catalog/admin/phpinfo.php~ new file mode 100644 index 0000000..65901f3 --- /dev/null +++ b/catalog/admin/phpinfo.php~ @@ -0,0 +1,8 @@ + diff --git a/catalog/admin/ps.php b/catalog/admin/ps.php new file mode 100644 index 0000000..93c6d71 --- /dev/null +++ b/catalog/admin/ps.php @@ -0,0 +1,17 @@ + diff --git a/catalog/admin/ps.php~ b/catalog/admin/ps.php~ new file mode 100644 index 0000000..f21f9eb --- /dev/null +++ b/catalog/admin/ps.php~ @@ -0,0 +1,16 @@ + diff --git a/catalog/admin/review.php b/catalog/admin/review.php new file mode 100644 index 0000000..745dc26 --- /dev/null +++ b/catalog/admin/review.php @@ -0,0 +1,79 @@ +logger = new logger (); +$db = $config->db (); + +getstr ("mode"); +getint ("fk_reviews"); +getint ("fk_books"); +$caption = ucfirst ($mode) . " Review"; + +$f = new SQLForm (); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this review."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + if (ismode ("add")) { + $f->SQLInject ("fk_books", "fk_books", SQLINT); + } + $f->SQLSelect ("fk_reviewers", "fk_reviewers", "Reviewer", SQLINT, 10, 2, true, + "select pk as value, name as caption from reviews.reviewers order by caption"); + $f->ToolTip ("Name of the reviewer."); + + $f->Text ("title", "title", "Title", SQLCHAR, 80, 80, true); + $f->ToolTip ("Enter a title for the review, eg. Summary, Review, Excerpts, Critique"); + + $f->TextArea ("review", "review", "Review", SQLCHAR, 20, 80, true); + $f->ToolTip ("Enter a review for the work."); + + $f->LoadData ("select * from reviews.reviews where pk = $fk_reviews"); +} +$f->Hidden ("fk_reviews"); +$f->Hidden ("fk_books"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into reviews.reviews " . $sql)) { + $msg = "msg=Review added !"; + } else { + $msg = "errormsg=Could not add review!"; + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update reviews.reviews set " . $sql . "where pk = $fk_reviews")) { + $msg = "msg=Review modified !"; + } else { + $msg = "errormsg=Could not modify review !"; + } + } +} +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from reviews.reviews where pk = $fk_reviews")) { + $msg = "msg=Review deleted !"; + } else { + $msg = "errormsg=Could not delete review !"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption); +$f->Output ($caption, $caption); +pagefooter (); + +?> diff --git a/catalog/admin/review.php~ b/catalog/admin/review.php~ new file mode 100644 index 0000000..0d54fd0 --- /dev/null +++ b/catalog/admin/review.php~ @@ -0,0 +1,78 @@ +logger = new logger (); +$db = $config->db (); + +getstr ("mode"); +getint ("fk_reviews"); +getint ("fk_books"); +$caption = ucfirst ($mode) . " Review"; + +$f = new SQLForm (); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this review."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + if (ismode ("add")) { + $f->SQLInject ("fk_books", "fk_books", SQLINT); + } + $f->SQLSelect ("fk_reviewers", "fk_reviewers", "Reviewer", SQLINT, 10, 2, true, + "select pk as value, name as caption from reviews.reviewers order by caption"); + $f->ToolTip ("Name of the reviewer."); + + $f->Text ("title", "title", "Title", SQLCHAR, 80, 80, true); + $f->ToolTip ("Enter a title for the review, eg. Summary, Review, Excerpts, Critique"); + + $f->TextArea ("review", "review", "Review", SQLCHAR, 20, 80, true); + $f->ToolTip ("Enter a review for the work."); + + $f->LoadData ("select * from reviews.reviews where pk = $fk_reviews"); +} +$f->Hidden ("fk_reviews"); +$f->Hidden ("fk_books"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into reviews.reviews " . $sql)) { + $msg = "msg=Review added !"; + } else { + $msg = "errormsg=Could not add review!"; + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update reviews.reviews set " . $sql . "where pk = $fk_reviews")) { + $msg = "msg=Review modified !"; + } else { + $msg = "errormsg=Could not modify review !"; + } + } +} +if (isupdatemode ("delete")) { + if ($db->Exec ("delete from reviews.reviews where pk = $fk_reviews")) { + $msg = "msg=Review deleted !"; + } else { + $msg = "errormsg=Could not delete review !"; + } +} + +if (isupdate ()) { + header ("Location: book?mode=edit&fk_books=$fk_books&$msg"); + return; +} + +pageheader ($caption); +$f->Output ($caption, $caption); +pagefooter (); + +?> diff --git a/catalog/admin/rm-rf.php b/catalog/admin/rm-rf.php new file mode 100644 index 0000000..698946d --- /dev/null +++ b/catalog/admin/rm-rf.php @@ -0,0 +1,17 @@ + diff --git a/catalog/admin/rm-rf.php~ b/catalog/admin/rm-rf.php~ new file mode 100644 index 0000000..d573d4a --- /dev/null +++ b/catalog/admin/rm-rf.php~ @@ -0,0 +1,16 @@ + diff --git a/catalog/admin/robot-activity.php b/catalog/admin/robot-activity.php new file mode 100644 index 0000000..61fbd5e --- /dev/null +++ b/catalog/admin/robot-activity.php @@ -0,0 +1,246 @@ +host ($ip); +} + +class CalcFieldHost { + function f ($db) { + $ip = $db->get ("ip", SQLCHAR); + $host = hr_host ($ip); + $host = preg_replace ("/[^.]+\.[^.]+$/", "\xE2\x80\x8B\\0", $host); + return $host; + } +} + +class CalcFieldDuration { + function f ($db) { + return hr_time_diff ($db->get ("firstseen", SQLDATE), $db->get ("lastseen", SQLDATE)); + } +} + +class CalcFieldRate { + function f ($db) { + return round (3600 * $db->get ("hits", SQLINT) / ($db->get ("lastseen", SQLDATE) - $db->get ("firstseen", SQLDATE))); + } +} + +class CalcFieldLastSeen { + function f ($db) { + return hr_ago ($db->get ("lastseen", SQLDATE)); + } +} + +class CalcFieldBlocked { + function f ($db) { + $ip = htmlspecialchars ($db->get ("ip", SQLCHAR)); + $b = "block"; + return $db->get ("blocked", SQLBOOL) ? "blocked" : $b; + } +} + +class CalcFieldExpires { + function f ($db) { + return hr_in ($db->get ("expires", SQLDATE)); + } +} + +class CalcFieldRBL { + function __construct ($list) { + $this->list = $list; + } + function f ($db) { + $ip = fixnetwork ($db->get ("ip", SQLCHAR)); + $reverse_ip = join (".", array_reverse (explode (".", $ip))); + $host = gethostbyname ("$reverse_ip.$this->list"); + // return $host; // debug + return strncmp ($host, "127.", 4) ? "" : "Yes"; + } +} + +class RobotHitTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("c_blocked", "Block", "narrow"); + $this->lastcolumn->raw = 1; + $this->lastcolumn->SetTitle ("Block this IP."); + + $this->AddColumn ("delete", "Delete", "narrow"); + $this->lastcolumn->SetTitle ("Delete this robot from watch list."); + + $this->AddSimpleColumn ("c_last", "Seen"); + $this->lastcolumn->SetTitle ("Last access."); + + $this->AddSimpleColumn ("c_dur", "For"); + $this->lastcolumn->SetTitle ("Total duration of access."); + + $this->AddSimpleColumn ("ip", "IP"); + $this->lastcolumn->SetTitle ("IP address."); + + $this->AddSimpleColumn ("c_host", "Host"); + $this->lastcolumn->f = create_function ('$raw', 'return $raw;'); + $this->lastcolumn->raw = 1; + $this->lastcolumn->SetTitle ("Host name. ??? if reverse lookup failed."); + + $this->AddColumn ("whois", "Whois", "narrow"); + $this->lastcolumn->SetTitle ("Start a whois query."); + + $this->AddSimpleColumn ("c_rate", "Rate", "narrow right"); + $this->lastcolumn->SetTitle ("Total hit rate / hour."); + + $this->AddSimpleColumn ("hits", "Total", "narrow right"); + $this->lastcolumn->SetTitle ("Total hits."); + + $this->AddSimpleColumn ("rhits", "Res.", "narrow right"); + $this->lastcolumn->SetTitle ("Hits in robot-restricted area. Should be zero."); + + $this->AddSimpleColumn ("hhits", "Hp", "narrow right"); + $this->lastcolumn->SetTitle ("Hits in honeypot. Should be zero."); + + $this->AddSimpleColumn ("ua", "User-Agent"); + $this->lastcolumn->SetTitle ("User Agent"); + + } + function startrow ($db) { + $blocked = $db->get ("blocked", SQLBOOL); + $style = $blocked ? " style=\"color: gray;\"" : ""; + echo (" "); + } +} + +class RobotBlockedTable extends ListTable { + function __construct () { + $this->AddColumn ("unblock", "Unblock", "narrow"); + $this->lastcolumn->SetTitle ("Unblock this IP."); + + $this->AddSimpleColumn ("ip", "IP"); + $this->lastcolumn->SetTitle ("IP address."); + + $this->AddSimpleColumn ("c_host", "Host"); + $this->lastcolumn->f = create_function ('$raw', 'return $raw;'); + $this->lastcolumn->raw = 1; + $this->lastcolumn->SetTitle ("Host name. ??? if reverse lookup failed."); + + $this->AddColumn ("whois", "Whois", "narrow"); + $this->lastcolumn->SetTitle ("Start a whois query."); + + $this->AddSimpleColumn ("c_expires", "Expires"); + $this->lastcolumn->SetTitle ("Block expires."); + + } +} + +$db = $config->db (); +$r = new robots (); + +getstr ("block"); +getstr ("unblock"); +getstr ("delete"); + +if ($block) { + $ip = long2ip (ip2long ($block)); + $r->block ($ip); + $host = hr_host ($ip); + $msg = "Robot $host ($ip) blocked"; + // redirect else we would block again on page refresh + header ("Location: robot-activity?msg=$msg"); + return; +} + +if ($unblock) { + $ip = long2ip (ip2long ($unblock)); + $r->unblock ($ip); + $host = hr_host ($ip); + $msg = "Robot $host ($ip) unblocked"; + header ("Location: robot-activity?msg=$msg"); + return; +} + +if ($delete) { + $ip = long2ip (ip2long ($delete)); + $r->delete ($ip); + $host = hr_host ($ip); + $msg = "Robot $host ($ip) deleted"; + header ("Location: robot-activity?msg=$msg"); + return; +} + +pageheader ($caption = "Robot Activity Monitor"); + +getstr ("msg"); +getstr ("errormsg"); + +if (!empty ($msg)) msg ($msg); +if (!empty ($errormsg)) error_msg ($msg); + +p ("Time: " . date ("Y-m-d H:i:s")); + +$db->exec ("select robots.ips.*, robots.blocks.expires > timestamp 'now' as blocked from robots.ips +left join robots.blocks on robots.ips.ip = robots.blocks.ip +where + (robots.blocks.expires > timestamp 'now') + or ((hits > 1000) and (lastseen - firstseen) / hits < interval '2 seconds') + or ((rhits > 100) and (lastseen - firstseen) / (rhits + 1) < interval '20 seconds') + or (hhits > 10) +order by not (robots.blocks.expires > timestamp 'now'), ((lastseen - firstseen) / hits) limit 100; +"); + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_dur"] = new CalcFieldDuration (); +$db->calcfields ["c_last"] = new CalcFieldLastSeen (); +$db->calcfields ["c_blocked"] = new CalcFieldBlocked (); +$db->calcfields ["c_rate"] = new CalcFieldRate (); + +// $db->calcfields ["c_isdialup"] = new CalcFieldRBL ("dul.dnsbl.sorbs.net"); +// $db->calcfields ["c_spews"] = new CalcFieldRBL ("l2.spews.dnsbl.sorbs.net"); + +$table = new RobotHitTable (); +$table->PrintTable ($db, "Recently Active Robots"); + +$db->exec ("select * from robots.blocks where expires > timestamp 'now' order by ip;"); + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_expires"] = new CalcFieldExpires (); + +$table = new RobotBlockedTable (); +$table->PrintTable ($db, "Blocked Robots"); + +pagefooter (); + +?> diff --git a/catalog/admin/robot-activity.php~ b/catalog/admin/robot-activity.php~ new file mode 100644 index 0000000..650f0e4 --- /dev/null +++ b/catalog/admin/robot-activity.php~ @@ -0,0 +1,245 @@ +host ($ip); +} + +class CalcFieldHost { + function f ($db) { + $ip = $db->get ("ip", SQLCHAR); + $host = hr_host ($ip); + $host = preg_replace ("/[^.]+\.[^.]+$/", "\xE2\x80\x8B\\0", $host); + return $host; + } +} + +class CalcFieldDuration { + function f ($db) { + return hr_time_diff ($db->get ("firstseen", SQLDATE), $db->get ("lastseen", SQLDATE)); + } +} + +class CalcFieldRate { + function f ($db) { + return round (3600 * $db->get ("hits", SQLINT) / ($db->get ("lastseen", SQLDATE) - $db->get ("firstseen", SQLDATE))); + } +} + +class CalcFieldLastSeen { + function f ($db) { + return hr_ago ($db->get ("lastseen", SQLDATE)); + } +} + +class CalcFieldBlocked { + function f ($db) { + $ip = htmlspecialchars ($db->get ("ip", SQLCHAR)); + $b = "block"; + return $db->get ("blocked", SQLBOOL) ? "blocked" : $b; + } +} + +class CalcFieldExpires { + function f ($db) { + return hr_in ($db->get ("expires", SQLDATE)); + } +} + +class CalcFieldRBL { + function __construct ($list) { + $this->list = $list; + } + function f ($db) { + $ip = fixnetwork ($db->get ("ip", SQLCHAR)); + $reverse_ip = join (".", array_reverse (explode (".", $ip))); + $host = gethostbyname ("$reverse_ip.$this->list"); + // return $host; // debug + return strncmp ($host, "127.", 4) ? "" : "Yes"; + } +} + +class RobotHitTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("c_blocked", "Block", "narrow"); + $this->lastcolumn->raw = 1; + $this->lastcolumn->SetTitle ("Block this IP."); + + $this->AddColumn ("delete", "Delete", "narrow"); + $this->lastcolumn->SetTitle ("Delete this robot from watch list."); + + $this->AddSimpleColumn ("c_last", "Seen"); + $this->lastcolumn->SetTitle ("Last access."); + + $this->AddSimpleColumn ("c_dur", "For"); + $this->lastcolumn->SetTitle ("Total duration of access."); + + $this->AddSimpleColumn ("ip", "IP"); + $this->lastcolumn->SetTitle ("IP address."); + + $this->AddSimpleColumn ("c_host", "Host"); + $this->lastcolumn->f = create_function ('$raw', 'return $raw;'); + $this->lastcolumn->raw = 1; + $this->lastcolumn->SetTitle ("Host name. ??? if reverse lookup failed."); + + $this->AddColumn ("whois", "Whois", "narrow"); + $this->lastcolumn->SetTitle ("Start a whois query."); + + $this->AddSimpleColumn ("c_rate", "Rate", "narrow right"); + $this->lastcolumn->SetTitle ("Total hit rate / hour."); + + $this->AddSimpleColumn ("hits", "Total", "narrow right"); + $this->lastcolumn->SetTitle ("Total hits."); + + $this->AddSimpleColumn ("rhits", "Res.", "narrow right"); + $this->lastcolumn->SetTitle ("Hits in robot-restricted area. Should be zero."); + + $this->AddSimpleColumn ("hhits", "Hp", "narrow right"); + $this->lastcolumn->SetTitle ("Hits in honeypot. Should be zero."); + + $this->AddSimpleColumn ("ua", "User-Agent"); + $this->lastcolumn->SetTitle ("User Agent"); + + } + function startrow ($db) { + $blocked = $db->get ("blocked", SQLBOOL); + $style = $blocked ? " style=\"color: gray;\"" : ""; + echo (" "); + } +} + +class RobotBlockedTable extends ListTable { + function __construct () { + $this->AddColumn ("unblock", "Unblock", "narrow"); + $this->lastcolumn->SetTitle ("Unblock this IP."); + + $this->AddSimpleColumn ("ip", "IP"); + $this->lastcolumn->SetTitle ("IP address."); + + $this->AddSimpleColumn ("c_host", "Host"); + $this->lastcolumn->f = create_function ('$raw', 'return $raw;'); + $this->lastcolumn->raw = 1; + $this->lastcolumn->SetTitle ("Host name. ??? if reverse lookup failed."); + + $this->AddColumn ("whois", "Whois", "narrow"); + $this->lastcolumn->SetTitle ("Start a whois query."); + + $this->AddSimpleColumn ("c_expires", "Expires"); + $this->lastcolumn->SetTitle ("Block expires."); + + } +} + +$db = $config->db (); +$r = new robots (); + +getstr ("block"); +getstr ("unblock"); +getstr ("delete"); + +if ($block) { + $ip = long2ip (ip2long ($block)); + $r->block ($ip); + $host = hr_host ($ip); + $msg = "Robot $host ($ip) blocked"; + // redirect else we would block again on page refresh + header ("Location: robot-activity?msg=$msg"); + return; +} + +if ($unblock) { + $ip = long2ip (ip2long ($unblock)); + $r->unblock ($ip); + $host = hr_host ($ip); + $msg = "Robot $host ($ip) unblocked"; + header ("Location: robot-activity?msg=$msg"); + return; +} + +if ($delete) { + $ip = long2ip (ip2long ($delete)); + $r->delete ($ip); + $host = hr_host ($ip); + $msg = "Robot $host ($ip) deleted"; + header ("Location: robot-activity?msg=$msg"); + return; +} + +pageheader ($caption = "Robot Activity Monitor"); + +getstr ("msg"); +getstr ("errormsg"); + +if (!empty ($msg)) msg ($msg); +if (!empty ($errormsg)) error_msg ($msg); + +p ("Time: " . date ("Y-m-d H:i:s")); + +$db->exec ("select robots.ips.*, robots.blocks.expires > timestamp 'now' as blocked from robots.ips +left join robots.blocks on robots.ips.ip = robots.blocks.ip +where + (robots.blocks.expires > timestamp 'now') + or ((hits > 1000) and (lastseen - firstseen) / hits < interval '2 seconds') + or ((rhits > 100) and (lastseen - firstseen) / (rhits + 1) < interval '20 seconds') + or (hhits > 10) +order by not (robots.blocks.expires > timestamp 'now'), ((lastseen - firstseen) / hits) limit 100; +"); + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_dur"] = new CalcFieldDuration (); +$db->calcfields ["c_last"] = new CalcFieldLastSeen (); +$db->calcfields ["c_blocked"] = new CalcFieldBlocked (); +$db->calcfields ["c_rate"] = new CalcFieldRate (); + +// $db->calcfields ["c_isdialup"] = new CalcFieldRBL ("dul.dnsbl.sorbs.net"); +// $db->calcfields ["c_spews"] = new CalcFieldRBL ("l2.spews.dnsbl.sorbs.net"); + +$table = new RobotHitTable (); +$table->PrintTable ($db, "Recently Active Robots"); + +$db->exec ("select * from robots.blocks where expires > timestamp 'now' order by ip;"); + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_expires"] = new CalcFieldExpires (); + +$table = new RobotBlockedTable (); +$table->PrintTable ($db, "Blocked Robots"); + +pagefooter (); + +?> diff --git a/catalog/admin/robot-block.php b/catalog/admin/robot-block.php new file mode 100644 index 0000000..5c41fb1 --- /dev/null +++ b/catalog/admin/robot-block.php @@ -0,0 +1,147 @@ +documentroot/.htaccess"; + +function fixnetwork ($ip) { + if (($pos = strpos ($ip, "/")) !== false) { + $ip = substr ($ip, 0, $pos); + $ip = long2ip (ip2long ($ip) + 1); + } + return $ip; +} + +function hr_time_diff ($t1, $t2) { + $diff = $t2 - $t1; + if ($diff < 60) + return ""; + if ($diff < 3600) + return round ($diff / 60) . " m"; + if ($diff < 36000) + return round ($diff / 3600, 1) . " h"; + return round ($diff / 3600, 0) . " h"; +} + +function hr_ago ($t1) { + $d = hr_time_diff ($t1, time ()); + return $d ? "$d ago" : "now"; +} + +class CalcFieldHost { + function f ($db) { + $ip = $db->get ("ip", SQLCHAR); + $host = @gethostbyaddr ($ip); + if ($host == $ip) + return ""; + + $ipcheck = @gethostbyname ($host); + $host = preg_replace ("/[^.]+\.[^.]+$/", '\0', $host); + if ($ip != $ipcheck) + $host = "??? $host ???"; + + return $host; + } +} + +class CalcFieldDuration { + function f ($db) { + return hr_time_diff ($db->get ("firstseen", SQLDATE), $db->get ("lastseen", SQLDATE)); + } +} + +class CalcFieldLastSeen { + function f ($db) { + return hr_ago ($db->get ("lastseen", SQLDATE)); + } +} + +class CalcFieldBlocked { + function f ($db) { + global $blocked; + return in_array ($db->get ("ip", SQLCHAR), $blocked[1]) ? "B" : ""; + } +} + +class CalcFieldRBL { + function __construct ($list) { + $this->list = $list; + } + function f ($db) { + $ip = fixnetwork ($db->get ("ip", SQLCHAR)); + $reverse_ip = join (".", array_reverse (explode (".", $ip))); + $host = gethostbyname ("$reverse_ip.$this->list"); + // return $host; // debug + return strncmp ($host, "127.", 4) ? "" : "Yes"; + } +} + +class RobotHitTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("c_last", "Seen"); + $this->lastcolumn->SetTitle ("Last access."); + + $this->AddSimpleColumn ("c_dur", "For"); + $this->lastcolumn->SetTitle ("Total duration of access."); + + $this->AddSimpleColumn ("ip", "IP"); + $this->lastcolumn->SetTitle ("IP address."); + + $this->AddSimpleColumn ("c_blocked", "B", "narrow"); + $this->lastcolumn->SetTitle ("'B' if blocked."); + + $this->AddSimpleColumn ("c_host", "Host"); + $this->lastcolumn->f = create_function ('$raw', 'return $raw;'); + $this->lastcolumn->raw = 1; + $this->lastcolumn->SetTitle ("Host name. ??? if reverse lookup failed."); + + $this->AddColumn ("whois", "Whois", "narrow"); + $this->lastcolumn->SetTitle ("Start a whois query."); + + $this->AddSimpleColumn ("hits", "Total", "narrow right"); + $this->lastcolumn->SetTitle ("Total hits."); + + $this->AddSimpleColumn ("rhits", "Restricted", "narrow right"); + $this->lastcolumn->SetTitle ("Hits in robot-restricted area. Should be zero."); + + $this->AddSimpleColumn ("hhits", "Honeypot", "narrow right"); + $this->lastcolumn->SetTitle ("Hits in honeypot. Should be zero."); + } +} + +$db = $config->db (); + +pageheader ($caption = "Robot Activity Monitor"); + +$htaccess = file_get_contents ($htaccess); +preg_match_all ("/^Deny\s+From\s+([\d.]+)$/im", $htaccess, $blocked, PREG_PATTERN_ORDER); + +/* +foreach ($blocked[1] as $ip) { + p ($ip); +} +*/ + +p ("Time: " . date ("Y-m-d H:i:s")); + +$db->exec ("select * from robots.ips +order by hits + hhits * 100 desc limit 20; +"); + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_dur"] = new CalcFieldDuration (); +$db->calcfields ["c_last"] = new CalcFieldLastSeen (); +$db->calcfields ["c_blocked"] = new CalcFieldBlocked (); + +// $db->calcfields ["c_isdialup"] = new CalcFieldRBL ("dul.dnsbl.sorbs.net"); +// $db->calcfields ["c_spews"] = new CalcFieldRBL ("l2.spews.dnsbl.sorbs.net"); + +$table = new RobotHitTable (); +$table->PrintTable ($db, "Recently Active Robots"); + +pagefooter (); + +?> diff --git a/catalog/admin/robot-block.php~ b/catalog/admin/robot-block.php~ new file mode 100644 index 0000000..5ab73cc --- /dev/null +++ b/catalog/admin/robot-block.php~ @@ -0,0 +1,146 @@ +documentroot/.htaccess"; + +function fixnetwork ($ip) { + if (($pos = strpos ($ip, "/")) !== false) { + $ip = substr ($ip, 0, $pos); + $ip = long2ip (ip2long ($ip) + 1); + } + return $ip; +} + +function hr_time_diff ($t1, $t2) { + $diff = $t2 - $t1; + if ($diff < 60) + return ""; + if ($diff < 3600) + return round ($diff / 60) . " m"; + if ($diff < 36000) + return round ($diff / 3600, 1) . " h"; + return round ($diff / 3600, 0) . " h"; +} + +function hr_ago ($t1) { + $d = hr_time_diff ($t1, time ()); + return $d ? "$d ago" : "now"; +} + +class CalcFieldHost { + function f ($db) { + $ip = $db->get ("ip", SQLCHAR); + $host = @gethostbyaddr ($ip); + if ($host == $ip) + return ""; + + $ipcheck = @gethostbyname ($host); + $host = preg_replace ("/[^.]+\.[^.]+$/", '\0', $host); + if ($ip != $ipcheck) + $host = "??? $host ???"; + + return $host; + } +} + +class CalcFieldDuration { + function f ($db) { + return hr_time_diff ($db->get ("firstseen", SQLDATE), $db->get ("lastseen", SQLDATE)); + } +} + +class CalcFieldLastSeen { + function f ($db) { + return hr_ago ($db->get ("lastseen", SQLDATE)); + } +} + +class CalcFieldBlocked { + function f ($db) { + global $blocked; + return in_array ($db->get ("ip", SQLCHAR), $blocked[1]) ? "B" : ""; + } +} + +class CalcFieldRBL { + function __construct ($list) { + $this->list = $list; + } + function f ($db) { + $ip = fixnetwork ($db->get ("ip", SQLCHAR)); + $reverse_ip = join (".", array_reverse (explode (".", $ip))); + $host = gethostbyname ("$reverse_ip.$this->list"); + // return $host; // debug + return strncmp ($host, "127.", 4) ? "" : "Yes"; + } +} + +class RobotHitTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("c_last", "Seen"); + $this->lastcolumn->SetTitle ("Last access."); + + $this->AddSimpleColumn ("c_dur", "For"); + $this->lastcolumn->SetTitle ("Total duration of access."); + + $this->AddSimpleColumn ("ip", "IP"); + $this->lastcolumn->SetTitle ("IP address."); + + $this->AddSimpleColumn ("c_blocked", "B", "narrow"); + $this->lastcolumn->SetTitle ("'B' if blocked."); + + $this->AddSimpleColumn ("c_host", "Host"); + $this->lastcolumn->f = create_function ('$raw', 'return $raw;'); + $this->lastcolumn->raw = 1; + $this->lastcolumn->SetTitle ("Host name. ??? if reverse lookup failed."); + + $this->AddColumn ("whois", "Whois", "narrow"); + $this->lastcolumn->SetTitle ("Start a whois query."); + + $this->AddSimpleColumn ("hits", "Total", "narrow right"); + $this->lastcolumn->SetTitle ("Total hits."); + + $this->AddSimpleColumn ("rhits", "Restricted", "narrow right"); + $this->lastcolumn->SetTitle ("Hits in robot-restricted area. Should be zero."); + + $this->AddSimpleColumn ("hhits", "Honeypot", "narrow right"); + $this->lastcolumn->SetTitle ("Hits in honeypot. Should be zero."); + } +} + +$db = $config->db (); + +pageheader ($caption = "Robot Activity Monitor"); + +$htaccess = file_get_contents ($htaccess); +preg_match_all ("/^Deny\s+From\s+([\d.]+)$/im", $htaccess, $blocked, PREG_PATTERN_ORDER); + +/* +foreach ($blocked[1] as $ip) { + p ($ip); +} +*/ + +p ("Time: " . date ("Y-m-d H:i:s")); + +$db->exec ("select * from robots.ips +order by hits + hhits * 100 desc limit 20; +"); + +$db->calcfields ["c_host"] = new CalcFieldHost (); +$db->calcfields ["c_dur"] = new CalcFieldDuration (); +$db->calcfields ["c_last"] = new CalcFieldLastSeen (); +$db->calcfields ["c_blocked"] = new CalcFieldBlocked (); + +// $db->calcfields ["c_isdialup"] = new CalcFieldRBL ("dul.dnsbl.sorbs.net"); +// $db->calcfields ["c_spews"] = new CalcFieldRBL ("l2.spews.dnsbl.sorbs.net"); + +$table = new RobotHitTable (); +$table->PrintTable ($db, "Recently Active Robots"); + +pagefooter (); + +?> diff --git a/catalog/admin/robot-terminator.php b/catalog/admin/robot-terminator.php new file mode 100644 index 0000000..c18c40d --- /dev/null +++ b/catalog/admin/robot-terminator.php @@ -0,0 +1,88 @@ +db (); +$db->exec ("update robots.blocks set expires = null where expires <= timestamp 'now'"); +$db->exec ("delete from robots.ips where lastseen < (timestamp 'now' - interval '1 days');"); +$db->exec ("vacuum robots.ips;"); + +$db2 = $config->db (); + +$db2->exec ("select robots.ips.*, robots.blocks.expires > timestamp 'now' as blocked from robots.ips +left join robots.blocks on robots.ips.ip = robots.blocks.ip + +where + (robots.blocks.expires is null) + and + ( + (hhits > 10) + or + ( + (rhits > 150) + and + (((lastseen - firstseen) / (rhits + 1)) < interval '10 seconds') + ) + ) +"); + + +if ($db2->FirstRow ()) { + $r = new robots (); + do { + $ip = $db2->get ("ip", SQLCHAR); + $r->block ($ip); + $host = $r->host ($ip); + + $to = $config->email_webmaster; + $subject = 'Blocked IP address'; + $message = "Robot $host ($ip) blocked."; + $headers = "From: robot-terminator@gutenberg.org\r\n" . + "Reply-To: $config->email_webmaster\r\n"; + + // echo "$message\n"; + + if (!mail ($to, $subject, $message, $headers)) { + echo ("could not send email\n"); + } + + } while ($db2->NextRow ()); +} + + +////////////////////////////////////////////////////////////////////////////// + +$s = "# this file is auto-generated by robot-terminator.php. do not edit.\n\n"; +$s .= "# permanent bans\n\n"; + +$s .= `grep -i '^Deny From [0-9]' $config->documentroot/.htaccess`; + +$s .= "\n# temporary bans\n\n"; + +$db->exec ("select * from robots.blocks where expires > timestamp 'now' order by ip"); +if ($db->FirstRow ()) { + do { + $ip = $db->get ("ip", SQLCHAR); + $s .= "Deny From $ip\n"; + } while ($db->NextRow ()); +} + +$s .= "\n# end of file\n"; + +// echo ($s); + +$file = "$config->documentroot/catalog/.htaccess"; + +$fp = fopen ($file, "w"); +if ($fp) { + fwrite ($fp, $s); + fclose ($fp); +} else { + echo ("Cannot write to $file\n"); +} + +?> diff --git a/catalog/admin/robot-terminator.php~ b/catalog/admin/robot-terminator.php~ new file mode 100644 index 0000000..d5769fc --- /dev/null +++ b/catalog/admin/robot-terminator.php~ @@ -0,0 +1,87 @@ +db (); +$db->exec ("update robots.blocks set expires = null where expires <= timestamp 'now'"); +$db->exec ("delete from robots.ips where lastseen < (timestamp 'now' - interval '1 days');"); +$db->exec ("vacuum robots.ips;"); + +$db2 = $config->db (); + +$db2->exec ("select robots.ips.*, robots.blocks.expires > timestamp 'now' as blocked from robots.ips +left join robots.blocks on robots.ips.ip = robots.blocks.ip + +where + (robots.blocks.expires is null) + and + ( + (hhits > 10) + or + ( + (rhits > 150) + and + (((lastseen - firstseen) / (rhits + 1)) < interval '10 seconds') + ) + ) +"); + + +if ($db2->FirstRow ()) { + $r = new robots (); + do { + $ip = $db2->get ("ip", SQLCHAR); + $r->block ($ip); + $host = $r->host ($ip); + + $to = $config->email_webmaster; + $subject = 'Blocked IP address'; + $message = "Robot $host ($ip) blocked."; + $headers = "From: robot-terminator@gutenberg.org\r\n" . + "Reply-To: $config->email_webmaster\r\n"; + + // echo "$message\n"; + + if (!mail ($to, $subject, $message, $headers)) { + echo ("could not send email\n"); + } + + } while ($db2->NextRow ()); +} + + +////////////////////////////////////////////////////////////////////////////// + +$s = "# this file is auto-generated by robot-terminator.php. do not edit.\n\n"; +$s .= "# permanent bans\n\n"; + +$s .= `grep -i '^Deny From [0-9]' $config->documentroot/.htaccess`; + +$s .= "\n# temporary bans\n\n"; + +$db->exec ("select * from robots.blocks where expires > timestamp 'now' order by ip"); +if ($db->FirstRow ()) { + do { + $ip = $db->get ("ip", SQLCHAR); + $s .= "Deny From $ip\n"; + } while ($db->NextRow ()); +} + +$s .= "\n# end of file\n"; + +// echo ($s); + +$file = "$config->documentroot/catalog/.htaccess"; + +$fp = fopen ($file, "w"); +if ($fp) { + fwrite ($fp, $s); + fclose ($fp); +} else { + echo ("Cannot write to $file\n"); +} + +?> \ No newline at end of file diff --git a/catalog/admin/stats.php b/catalog/admin/stats.php new file mode 100644 index 0000000..e05a53b --- /dev/null +++ b/catalog/admin/stats.php @@ -0,0 +1,173 @@ +db (); +$db->logger = new logger (); + +class AuthorsTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#author#", "Author"); + } +} + +pageheader("Various Statistics"); + +echo("

Author Stats

\n"); + +echo("

Note that there is still considerable error in the database of " . + "authors, due to incorrect spliting and merging of authors with " . + "similar or varying names.

\n"); + +echo("
    "); +$db->Exec("select count(*) from authors"); +echo("
  • Total Authors: " . $db->Get("count") . "
  • \n") ; +$db->Exec("select count(*) from authors where born_floor is null and " . + "born_ceil is null and died_floor is null and died_ceil is null"); +echo("
  • Authors with no birth or death dates: " . $db->Get("count") . + "
  • \n") ; +$db->Exec("select count(*) from authors where born_floor is not null " . + "and born_ceil is null and died_floor is null " . + "and died_ceil is null;"); +echo("
  • Authors with only a earliest birth year: " . $db->Get("count") . + "
  • \n") ; +$db->Exec("select count(*) from authors where born_floor is null " . + "and born_ceil is null and died_floor is not null " . + "and died_ceil is null;"); +echo("
  • Authors with only a earliest death year: " . $db->Get("count") . + "
  • \n") ; +echo ("
"); + +$table = new AuthorsTable (); +$db->Exec("select pk, author from authors where born_floor is null " . + "and died_floor is null and (born_ceil is not null or " . + "died_ceil is not null) order by author"); +$table->PrintTable($db, "Authors with only latest birth or death dates"); + +echo("
    "); +$db->Exec("select count(note) from authors;"); +echo("
  • # of Author entries with internal notes: " . $db->Get("count") . "
  • \n") ; +echo ("
"); + +$table = new AuthorsTable (); +$db->Exec("select pk, author from authors " . + "order by char_length(author) desc limit 20"); +$table->PrintTable($db, "20 longest Authors names"); + +$table = new AuthorsTable (); +$db->Exec("select pk, author from authors " . + "order by char_length(author) limit 20"); +$table->PrintTable($db, "20 shortest Authors names"); + +class AuthorsBirthDeathTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#author#", "Author"); + $this->AddSimpleColumn("born_floor", "Birth"); + $this->AddSimpleColumn("died_floor", "Death"); + } +} + +p("As a way to see what authors we have whose works are more likely to be " . + "in copyright, this is a list of all the authors born after the " . + "critical year of 1923."); +$table = new AuthorsBirthDeathTable (); +$db->Exec("select pk, author, born_floor, died_floor " . + "from authors where born_floor>1923 order by born_floor"); +$table->PrintTable($db, "Authors born after 1923"); + +$table = new AuthorsBirthDeathTable (); +$db->Exec("select pk, author, born_floor, died_floor from authors " . + "where died_floor-born_floor>100 order by author"); +$table->PrintTable($db, "Authors who lived more than 100 years"); + +$table = new AuthorsBirthDeathTable (); +$db->Exec("select pk, author, born_floor, died_floor from authors " . + "where died_floor-born_floor<20 order by author"); +$table->PrintTable($db, "Authors who lived less than 20 years"); + +$table = new AuthorsBirthDeathTable (); +$db->Exec("select pk, author, born_floor, died_floor from authors " . + "where died_floorPrintTable($db, "Authors born before they died"); + +echo("

Author URLs

\n"); /* Author URLs section */ + +echo("
    "); +$db->Exec("select count(authors.pk) as count from authors " . + "left join author_urls on authors.pk=author_urls.fk_authors " . + "where fk_authors is null"); +echo("
  • Author entries with no URLs attached: " . $db->Get("count") . + "
  • \n") ; +$db->Exec("select count(*) as count from (select fk_authors " . + "from author_urls group by fk_authors having " . + "count(fk_authors)=1) as foo"); +echo("
  • Author entries with a single URL: " . $db->Get("count") . + "
  • \n"); +$db->Exec("select count(*) as count from (select fk_authors " . + "from author_urls group by fk_authors having " . + "count(fk_authors)=2) as foo"); +echo("
  • Author entries with two URLs: " . $db->Get("count") . + "
  • \n"); +echo ("
"); + +class AuthorsWithMoreThan2URLsTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#author#", "Author"); + $this->AddSimpleColumn("count", "# of URLs"); + } +} +$table = new AuthorsWithMoreThan2URLsTable (); +$db->Exec("select fk_authors as pk, author, count(fk_authors) as count " . + "from author_urls join authors on fk_authors=authors.pk " . + "group by fk_authors, author having count(fk_authors)>2 " . + "order by count(fk_authors), author"); +$table->PrintTable($db, "Authors with more than 2 URLs attached"); + +echo("
    "); +$db->Exec("select count(*) from author_urls"); +echo("
  • Total # of URLs: " . $db->Get("count") . "
  • \n") ; +$db->Exec("select count(*) from " . + "(select distinct description from author_urls) as foo"); +echo("
  • # of different URL descriptions: " . $db->Get("count") . "
  • \n") ; +echo ("
"); +class URLDescriptionsTable extends ListTable { + function __construct () { + $this->AddSimpleColumn("description", "URL Description"); + $this->AddSimpleColumn("count", "# of Uses"); + } +} +$table = new URLDescriptionsTable (); +$db->Exec("select description, count(description) from author_urls group by description having count(description)>1 order by count(description) desc"); +$table->PrintTable($db, "URL descriptions used multiple times"); + +class RepeatedURLsTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#author#", "Author"); + $this->AddSimpleColumn("url", "URL"); + } +} +$table = new RepeatedURLsTable (); +$db->Exec("select fk_authors, author, url from author_urls " . + "join authors on fk_authors=authors.pk " . + "where url in (select url from author_urls " . + "group by url having count(url)>1) order by url;"); +$table->PrintTable($db, "URLs used multiple times"); + +pagefooter(); + +/* +echo("
    "); +$db->Exec(""); +echo("
  • : " . $db->Get("") . "
  • \n") ; +echo ("
"); +$table = new AuthorsTable (); +$db->Exec(""); +$table->PrintTable($db, "Authors "); +*/ diff --git a/catalog/admin/stats.php~ b/catalog/admin/stats.php~ new file mode 100644 index 0000000..6219fcf --- /dev/null +++ b/catalog/admin/stats.php~ @@ -0,0 +1,172 @@ +db (); +$db->logger = new logger (); + +class AuthorsTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#author#", "Author"); + } +} + +pageheader("Various Statistics"); + +echo("

Author Stats

\n"); + +echo("

Note that there is still considerable error in the database of " . + "authors, due to incorrect spliting and merging of authors with " . + "similar or varying names.

\n"); + +echo("
    "); +$db->Exec("select count(*) from authors"); +echo("
  • Total Authors: " . $db->Get("count") . "
  • \n") ; +$db->Exec("select count(*) from authors where born_floor is null and " . + "born_ceil is null and died_floor is null and died_ceil is null"); +echo("
  • Authors with no birth or death dates: " . $db->Get("count") . + "
  • \n") ; +$db->Exec("select count(*) from authors where born_floor is not null " . + "and born_ceil is null and died_floor is null " . + "and died_ceil is null;"); +echo("
  • Authors with only a earliest birth year: " . $db->Get("count") . + "
  • \n") ; +$db->Exec("select count(*) from authors where born_floor is null " . + "and born_ceil is null and died_floor is not null " . + "and died_ceil is null;"); +echo("
  • Authors with only a earliest death year: " . $db->Get("count") . + "
  • \n") ; +echo ("
"); + +$table = new AuthorsTable (); +$db->Exec("select pk, author from authors where born_floor is null " . + "and died_floor is null and (born_ceil is not null or " . + "died_ceil is not null) order by author"); +$table->PrintTable($db, "Authors with only latest birth or death dates"); + +echo("
    "); +$db->Exec("select count(note) from authors;"); +echo("
  • # of Author entries with internal notes: " . $db->Get("count") . "
  • \n") ; +echo ("
"); + +$table = new AuthorsTable (); +$db->Exec("select pk, author from authors " . + "order by char_length(author) desc limit 20"); +$table->PrintTable($db, "20 longest Authors names"); + +$table = new AuthorsTable (); +$db->Exec("select pk, author from authors " . + "order by char_length(author) limit 20"); +$table->PrintTable($db, "20 shortest Authors names"); + +class AuthorsBirthDeathTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#author#", "Author"); + $this->AddSimpleColumn("born_floor", "Birth"); + $this->AddSimpleColumn("died_floor", "Death"); + } +} + +p("As a way to see what authors we have whose works are more likely to be " . + "in copyright, this is a list of all the authors born after the " . + "critical year of 1923."); +$table = new AuthorsBirthDeathTable (); +$db->Exec("select pk, author, born_floor, died_floor " . + "from authors where born_floor>1923 order by born_floor"); +$table->PrintTable($db, "Authors born after 1923"); + +$table = new AuthorsBirthDeathTable (); +$db->Exec("select pk, author, born_floor, died_floor from authors " . + "where died_floor-born_floor>100 order by author"); +$table->PrintTable($db, "Authors who lived more than 100 years"); + +$table = new AuthorsBirthDeathTable (); +$db->Exec("select pk, author, born_floor, died_floor from authors " . + "where died_floor-born_floor<20 order by author"); +$table->PrintTable($db, "Authors who lived less than 20 years"); + +$table = new AuthorsBirthDeathTable (); +$db->Exec("select pk, author, born_floor, died_floor from authors " . + "where died_floorPrintTable($db, "Authors born before they died"); + +echo("

Author URLs

\n"); /* Author URLs section */ + +echo("
    "); +$db->Exec("select count(authors.pk) as count from authors " . + "left join author_urls on authors.pk=author_urls.fk_authors " . + "where fk_authors is null"); +echo("
  • Author entries with no URLs attached: " . $db->Get("count") . + "
  • \n") ; +$db->Exec("select count(*) as count from (select fk_authors " . + "from author_urls group by fk_authors having " . + "count(fk_authors)=1) as foo"); +echo("
  • Author entries with a single URL: " . $db->Get("count") . + "
  • \n"); +$db->Exec("select count(*) as count from (select fk_authors " . + "from author_urls group by fk_authors having " . + "count(fk_authors)=2) as foo"); +echo("
  • Author entries with two URLs: " . $db->Get("count") . + "
  • \n"); +echo ("
"); + +class AuthorsWithMoreThan2URLsTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#author#", "Author"); + $this->AddSimpleColumn("count", "# of URLs"); + } +} +$table = new AuthorsWithMoreThan2URLsTable (); +$db->Exec("select fk_authors as pk, author, count(fk_authors) as count " . + "from author_urls join authors on fk_authors=authors.pk " . + "group by fk_authors, author having count(fk_authors)>2 " . + "order by count(fk_authors), author"); +$table->PrintTable($db, "Authors with more than 2 URLs attached"); + +echo("
    "); +$db->Exec("select count(*) from author_urls"); +echo("
  • Total # of URLs: " . $db->Get("count") . "
  • \n") ; +$db->Exec("select count(*) from " . + "(select distinct description from author_urls) as foo"); +echo("
  • # of different URL descriptions: " . $db->Get("count") . "
  • \n") ; +echo ("
"); +class URLDescriptionsTable extends ListTable { + function __construct () { + $this->AddSimpleColumn("description", "URL Description"); + $this->AddSimpleColumn("count", "# of Uses"); + } +} +$table = new URLDescriptionsTable (); +$db->Exec("select description, count(description) from author_urls group by description having count(description)>1 order by count(description) desc"); +$table->PrintTable($db, "URL descriptions used multiple times"); + +class RepeatedURLsTable extends ListTable { + function __construct () { + $this->AddColumn("" . + "#author#", "Author"); + $this->AddSimpleColumn("url", "URL"); + } +} +$table = new RepeatedURLsTable (); +$db->Exec("select fk_authors, author, url from author_urls " . + "join authors on fk_authors=authors.pk " . + "where url in (select url from author_urls " . + "group by url having count(url)>1) order by url;"); +$table->PrintTable($db, "URLs used multiple times"); + +pagefooter(); + +/* +echo("
    "); +$db->Exec(""); +echo("
  • : " . $db->Get("") . "
  • \n") ; +echo ("
"); +$table = new AuthorsTable (); +$db->Exec(""); +$table->PrintTable($db, "Authors "); +*/ diff --git a/catalog/admin/subj_locc_by_etext.php b/catalog/admin/subj_locc_by_etext.php new file mode 100644 index 0000000..00df345 --- /dev/null +++ b/catalog/admin/subj_locc_by_etext.php @@ -0,0 +1,68 @@ +db (); +$db->logger = new logger (); +if ($within_the_last) { + pageheader("List of Books released within the last $within_the_last days lacking a Subject and/or a LoCC"); + } else { + pageheader("List of Books lacking a Subject and/or a LoCC"); + } +class SubjLoccByEtextTable extends MoreTable { + function __construct () { + $this->AddColumn ("#pk#", + "Etext Nr. (edit link)", "right"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddColumn ("#title#", + "Title (bibrec link)"); + $this->AddColumn ("" . + "       ", + "No Subj", "narrow"); + $this->AddColumn ("" . + "       ", + "No LoCC", "narrow"); + $this->limit = 30; + $this->relay = array (); + } +} +$table = new SubjLoccByEtextTable (); +$sql="select distinct on (fk_books) fk_books as pk, text as title, author, " . + "(case when fk_subjects is null then 'black' end) as nosubj, " . + "(case when fk_loccs is null then 'black' end) as nolocc " . + "from attributes left join mn_books_subjects using (fk_books) " . + "left join mn_books_loccs using (fk_books) " . + "join mn_books_authors using (fk_books) " . + "join authors on authors.pk=fk_authors "; + +if ($within_the_last) { + $sql=$sql . "join books on books.pk=fk_books "; +} + +// gbn: the fk_roles skips records that don't have an Author or Creator: + $sql=$sql . "where fk_attriblist=245 and "; // . +// "fk_roles in ('aut', 'cre') and heading=1 and "; + +if ($within_the_last) { + $sql=$sql . "books.release_date >= current_date - interval '$within_the_last days' and "; +} + +$sql=$sql . "((fk_subjects is null) or (fk_loccs is null)) " . + "order by fk_books, text, author" . + $table->MkOffset (); + +// echo ("

$sql

"); + +$db->Exec($sql); +# gbn: 20091213 +print "

Last day only

\n"; + + +$table->PrintTable($db, "Books lacking a Subject and/or a LoCC"); + +pagefooter(); diff --git a/catalog/admin/subj_locc_by_etext.php.20090831 b/catalog/admin/subj_locc_by_etext.php.20090831 new file mode 100644 index 0000000..5e7ff9d --- /dev/null +++ b/catalog/admin/subj_locc_by_etext.php.20090831 @@ -0,0 +1,55 @@ +db (); +$db->logger = new logger (); +if ($within_the_last) { + pageheader("List of Books released within the last $within_the_last days lacking a Subject and/or a LoCC"); + } else { + pageheader("List of Books lacking a Subject and/or a LoCC"); + } +class SubjLoccByEtextTable extends MoreTable { + function SubjLoccByEtextTable () { + $this->AddColumn ("#pk#", + "Etext Nr. (edit link)", "right"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddColumn ("#title#", + "Title (bibrec link)"); + $this->AddColumn ("" . + "       ", + "No Subj", "narrow"); + $this->AddColumn ("" . + "       ", + "No LoCC", "narrow"); + $this->limit = 30; + $this->relay = array (); + } +} +$table = new SubjLoccByEtextTable (); +$sql="select distinct on (fk_books) fk_books as pk, text as title, author, " . + "(case when fk_subjects is null then 'black' end) as nosubj, " . + "(case when fk_loccs is null then 'black' end) as nolocc " . + "from attributes left join mn_books_subjects using (fk_books) " . + "left join mn_books_loccs using (fk_books) " . + "join mn_books_authors using (fk_books) " . + "join authors on authors.pk=fk_authors "; +if ($within_the_last) { + $sql=$sql . "join books on books.pk=fk_books "; + } +$sql=$sql . "where fk_attriblist=245 and " . + "fk_roles='aut' and heading=1 and "; +if ($within_the_last) { + $sql=$sql . "release_date>=(current_date-integer '$within_the_last') and "; + } +$sql=$sql . "((fk_subjects is null) or (fk_loccs is null)) " . + "order by fk_books, text, author" . + $table->MkOffset (); +$db->Exec($sql); +$table->PrintTable($db, "Books lacking a Subject and/or a LoCC"); + +pagefooter(); \ No newline at end of file diff --git a/catalog/admin/subj_locc_by_etext.php~ b/catalog/admin/subj_locc_by_etext.php~ new file mode 100644 index 0000000..a9c0bb3 --- /dev/null +++ b/catalog/admin/subj_locc_by_etext.php~ @@ -0,0 +1,67 @@ +db (); +$db->logger = new logger (); +if ($within_the_last) { + pageheader("List of Books released within the last $within_the_last days lacking a Subject and/or a LoCC"); + } else { + pageheader("List of Books lacking a Subject and/or a LoCC"); + } +class SubjLoccByEtextTable extends MoreTable { + function __construct () { + $this->AddColumn ("#pk#", + "Etext Nr. (edit link)", "right"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddColumn ("#title#", + "Title (bibrec link)"); + $this->AddColumn ("" . + "       ", + "No Subj", "narrow"); + $this->AddColumn ("" . + "       ", + "No LoCC", "narrow"); + $this->limit = 30; + $this->relay = array (); + } +} +$table = new SubjLoccByEtextTable (); +$sql="select distinct on (fk_books) fk_books as pk, text as title, author, " . + "(case when fk_subjects is null then 'black' end) as nosubj, " . + "(case when fk_loccs is null then 'black' end) as nolocc " . + "from attributes left join mn_books_subjects using (fk_books) " . + "left join mn_books_loccs using (fk_books) " . + "join mn_books_authors using (fk_books) " . + "join authors on authors.pk=fk_authors "; + +if ($within_the_last) { + $sql=$sql . "join books on books.pk=fk_books "; +} + +// gbn: the fk_roles skips records that don't have an Author or Creator: + $sql=$sql . "where fk_attriblist=245 and "; // . +// "fk_roles in ('aut', 'cre') and heading=1 and "; + +if ($within_the_last) { + $sql=$sql . "books.release_date >= current_date - interval '$within_the_last days' and "; +} + +$sql=$sql . "((fk_subjects is null) or (fk_loccs is null)) " . + "order by fk_books, text, author" . + $table->MkOffset (); + +// echo ("

$sql

"); + +$db->Exec($sql); +# gbn: 20091213 +print "

Last day only

\n"; + + +$table->PrintTable($db, "Books lacking a Subject and/or a LoCC"); + +pagefooter(); diff --git a/catalog/admin/subject.php b/catalog/admin/subject.php new file mode 100644 index 0000000..9429dad --- /dev/null +++ b/catalog/admin/subject.php @@ -0,0 +1,136 @@ +AddColumn ("#pk#", + "Etext Nr.", "right", "1*"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddSimpleColumn ("title", "Title"); + $this->limit = 25; + $this->relay = array ("fk_subjects", "mode", "filter"); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_subjects"); +getstr ("filter"); + +$subject_name = ""; +if ($db->Exec("select subject from subjects where pk = $fk_subjects")) { +#it will make life nicer if the message includes *what* subject was linked. + $subject_name = $db->Get("subject"); + } +if (!$subject_name) { + /* if getting the actual name fails for some reason, use the internal number instead; + at least it is something...*/ + $subject_name = "Internal #: $fk_subjects"; + } + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_subjects " . + "where fk_subjects = $fk_subjects"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + $f->SubCaption ("Warning: There are $cnt books related to \"$subject_name\". "); + } + $f->SubCaption ("You are about to delete \"$subject_name\"."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("subject", "subject", "Subject", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from subjects where pk = $fk_subjects"); + +} +$f->Hidden ("fk_subjects"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + $subject_name=htmlspecialchars(urldecode($_POST["subject"])); + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into subjects " . $sql)) { + msg ("Subject '$subject_name' added !"); + } else { + error_msg ("Could not add subject '$subject_name'!"); + } + $db->Exec ("select last_value from subjects_pk_seq"); + $fk_subjects=$db->Get("last_value"); + } +} +if (isupdatemode ("edit")) { + $subject_name=htmlspecialchars(urldecode($_POST["subject"])); + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update subjects set " . $sql . "where pk = $fk_subjects")) { + msg ("Subject '$subject_name' modified !"); + } else { + error_msg ("Could not modify subject '$subject_name'!"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_books_subjects where fk_subjects = $fk_subjects"); + if ($db->Exec ("delete from subjects where pk = $fk_subjects")) { + msg ("Subject '$subject_name' deleted !"); + } else { + error_msg ("Could not delete subject '$subject_name'!"); + } +} + +if ($fk_subjects) { + echo("Internal Subject #: $fk_subjects
"); + //Only display the Internal # when it exists. ;-) +} +if (isupdate ()) { + if (!isupdatemode ("delete")) { + echo ("

" . + "Back to Subject \"$subject_name\"

\n\n"); + } +} else { + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + echo ("
" . + "" . + "Delete Subject\n"); + + $table = new ListBooksTable (); + $db->Exec ("select fk_books as pk, text as title, author " . + "from (mn_books_subjects join attributes using (fk_books)) " . + "left join mn_books_authors using (fk_books) " . + "left join authors on authors.pk = fk_authors " . + "where fk_subjects=$fk_subjects and fk_attriblist in (240, 245, 246) " . + "order by author, title " . + $table->MkOffset ()); + if ($db->Get("pk")) { + $table->PrintTable ($db, "Books for Subject"); + } else { + echo ("

There are no books with this Subject!

\n"); + } + } +} + +echo ("

" . + "Back to Subject List

\n"); +echo ("

" . + "Add a new Subject

\n\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/subject.php~ b/catalog/admin/subject.php~ new file mode 100644 index 0000000..0c05678 --- /dev/null +++ b/catalog/admin/subject.php~ @@ -0,0 +1,135 @@ +AddColumn ("#pk#", + "Etext Nr.", "right", "1*"); + $this->AddSimpleColumn ("author", "Author"); + $this->AddSimpleColumn ("title", "Title"); + $this->limit = 25; + $this->relay = array ("fk_subjects", "mode", "filter"); + } +} + +$db = $config->db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_subjects"); +getstr ("filter"); + +$subject_name = ""; +if ($db->Exec("select subject from subjects where pk = $fk_subjects")) { +#it will make life nicer if the message includes *what* subject was linked. + $subject_name = $db->Get("subject"); + } +if (!$subject_name) { + /* if getting the actual name fails for some reason, use the internal number instead; + at least it is something...*/ + $subject_name = "Internal #: $fk_subjects"; + } + +if (ismode ("delete")) { + $db->Exec ("select count (*) as cnt from mn_books_subjects " . + "where fk_subjects = $fk_subjects"); + $cnt = $db->get ("cnt"); + if ($cnt > 0) { + $f->SubCaption ("Warning: There are $cnt books related to \"$subject_name\". "); + } + $f->SubCaption ("You are about to delete \"$subject_name\"."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("subject", "subject", "Subject", SQLCHAR, 80, 240, true); + $f->LoadData ("select * from subjects where pk = $fk_subjects"); + +} +$f->Hidden ("fk_subjects"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + $subject_name=htmlspecialchars(urldecode($_POST["subject"])); + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into subjects " . $sql)) { + msg ("Subject '$subject_name' added !"); + } else { + error_msg ("Could not add subject '$subject_name'!"); + } + $db->Exec ("select last_value from subjects_pk_seq"); + $fk_subjects=$db->Get("last_value"); + } +} +if (isupdatemode ("edit")) { + $subject_name=htmlspecialchars(urldecode($_POST["subject"])); + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update subjects set " . $sql . "where pk = $fk_subjects")) { + msg ("Subject '$subject_name' modified !"); + } else { + error_msg ("Could not modify subject '$subject_name'!"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_books_subjects where fk_subjects = $fk_subjects"); + if ($db->Exec ("delete from subjects where pk = $fk_subjects")) { + msg ("Subject '$subject_name' deleted !"); + } else { + error_msg ("Could not delete subject '$subject_name'!"); + } +} + +if ($fk_subjects) { + echo("Internal Subject #: $fk_subjects
"); + //Only display the Internal # when it exists. ;-) +} +if (isupdate ()) { + if (!isupdatemode ("delete")) { + echo ("

" . + "Back to Subject \"$subject_name\"

\n\n"); + } +} else { + $f->Output ($caption, $caption); + + if (ismode ("edit")) { + echo ("
" . + "" . + "Delete Subject\n"); + + $table = new ListBooksTable (); + $db->Exec ("select fk_books as pk, text as title, author " . + "from (mn_books_subjects join attributes using (fk_books)) " . + "left join mn_books_authors using (fk_books) " . + "left join authors on authors.pk = fk_authors " . + "where fk_subjects=$fk_subjects and fk_attriblist in (240, 245, 246) " . + "order by author, title " . + $table->MkOffset ()); + if ($db->Get("pk")) { + $table->PrintTable ($db, "Books for Subject"); + } else { + echo ("

There are no books with this Subject!

\n"); + } + } +} + +echo ("

" . + "Back to Subject List

\n"); +echo ("

" . + "Add a new Subject

\n\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/subjects_list.php b/catalog/admin/subjects_list.php new file mode 100644 index 0000000..5d66039 --- /dev/null +++ b/catalog/admin/subjects_list.php @@ -0,0 +1,47 @@ +AddColumn ("$prefix=edit&fk_subjects=#pk#\">Edit", + "$prefix=add\">Add", "left", "1%"); + $this->AddColumn ("$prefix=delete&fk_subjects=#pk#\">Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("subject", "Subject"); + $this->AddSimpleColumn("pk", "Internal #"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the subject (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. *Fiction) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from subjects where subject like '$filt%' order by subject;"); + $table = new ListSubjectsTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/subjects_list.php~ b/catalog/admin/subjects_list.php~ new file mode 100644 index 0000000..63dae96 --- /dev/null +++ b/catalog/admin/subjects_list.php~ @@ -0,0 +1,46 @@ +AddColumn ("$prefix=edit&fk_subjects=#pk#\">Edit", + "$prefix=add\">Add", "left", "1%"); + $this->AddColumn ("$prefix=delete&fk_subjects=#pk#\">Delete", + "", "left", "1%"); + $this->AddSimpleColumn ("subject", "Subject"); + $this->AddSimpleColumn("pk", "Internal #"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the subject (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. *Fiction) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from subjects where subject like '$filt%' order by subject;"); + $table = new ListSubjectsTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/swish-prog.php b/catalog/admin/swish-prog.php new file mode 100644 index 0000000..1f09acf --- /dev/null +++ b/catalog/admin/swish-prog.php @@ -0,0 +1,106 @@ +db (); +$db2 = $config->db (); + +function cmp ($a, $b) { + // sort on score descending + if ($a->score == $b->score) { + return 0; + } + return ($a->score > $b->score) ? -1 : 1; +} + +function book ($fk_books) { + global $config, $db2; + + // find best indexing candidate + + $db2->exec ("select pk, filename, fk_filetypes, fk_encodings from files " . + "where fk_books = $fk_books and fk_compressions = 'none' and obsoleted = 0 and " . + "fk_filetypes in ('txt', 'html', 'tex')"); + + if ($db2->FirstRow ()) { + do { + $o->filename = $db2->get ("filename", SQLCHAR); + $o->fk_filetypes = $db2->get ("fk_filetypes", SQLCHAR); + $o->fk_encodings = $db2->get ("fk_encodings", SQLCHAR); + $o->fk_files = $db2->get ("pk", SQLINT); + $o->score = 0; + $o->type = "TXT*"; + $files[] = $o; + } while ($db2->NextRow ()); + } + + for ($i = 0; $i < count ($files); $i++) { + $o =& $files[$i]; + if ($o->fk_filetypes == 'html') { + $o->score = 16; + $o->type = "HTML*"; + } + if ($o->fk_filetypes == 'tex') { + $o->score = 0; + } + if ($o->fk_filetypes == 'txt') { + // swish-e supports iso-8859-* only, exclude everything else from indexing + if (!isset ($o->fk_encodings) || $o->fk_encodings == "us-ascii") { + $o->score = 1; + } + if (!strncmp ($o->fk_encodings, "iso-", 4)) { + $o->score = 2; + } + if (!strncmp ($o->fk_encodings, "windows-", 8)) { + $o->score = 3; + } + } + } + if (count ($files) == 0) + return; + + usort ($files, "cmp"); + $maxscore = $files[0]->score; + + // careful! there may be more than one file per book to scan + + for ($i = 0; $i < count ($files); $i++) { + $o =& $files[$i]; + if ($o->score != $maxscore) { + continue; + } + if (is_link ("$config->filesroot/$o->filename")) { + continue; + } + if (!is_readable ("$config->filesroot/$o->filename")) { + continue; + } + $s = @stat ("$config->filesroot/$o->filename"); + if (!$s) { + continue; + } + + // ok, send it out + echo ("Path-Name: $fk_books/$o->fk_files/$o->fk_filetypes/$o->fk_encodings\n" . + "Content-Length: {$s['size']}\n" . + "Document-Type: $o->type\n\n"); + + readfile ("$config->filesroot/$o->filename"); + } +} + +$db->exec ("select pk from books order by pk"); + +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("pk", SQLINT); + book ($fk_books); + } while ($db->NextRow ()); +} + +?> diff --git a/catalog/admin/swish-prog.php~ b/catalog/admin/swish-prog.php~ new file mode 100644 index 0000000..377cd08 --- /dev/null +++ b/catalog/admin/swish-prog.php~ @@ -0,0 +1,105 @@ +db (); +$db2 = $config->db (); + +function cmp ($a, $b) { + // sort on score descending + if ($a->score == $b->score) { + return 0; + } + return ($a->score > $b->score) ? -1 : 1; +} + +function book ($fk_books) { + global $config, $db2; + + // find best indexing candidate + + $db2->exec ("select pk, filename, fk_filetypes, fk_encodings from files " . + "where fk_books = $fk_books and fk_compressions = 'none' and obsoleted = 0 and " . + "fk_filetypes in ('txt', 'html', 'tex')"); + + if ($db2->FirstRow ()) { + do { + $o->filename = $db2->get ("filename", SQLCHAR); + $o->fk_filetypes = $db2->get ("fk_filetypes", SQLCHAR); + $o->fk_encodings = $db2->get ("fk_encodings", SQLCHAR); + $o->fk_files = $db2->get ("pk", SQLINT); + $o->score = 0; + $o->type = "TXT*"; + $files[] = $o; + } while ($db2->NextRow ()); + } + + for ($i = 0; $i < count ($files); $i++) { + $o =& $files[$i]; + if ($o->fk_filetypes == 'html') { + $o->score = 16; + $o->type = "HTML*"; + } + if ($o->fk_filetypes == 'tex') { + $o->score = 0; + } + if ($o->fk_filetypes == 'txt') { + // swish-e supports iso-8859-* only, exclude everything else from indexing + if (!isset ($o->fk_encodings) || $o->fk_encodings == "us-ascii") { + $o->score = 1; + } + if (!strncmp ($o->fk_encodings, "iso-", 4)) { + $o->score = 2; + } + if (!strncmp ($o->fk_encodings, "windows-", 8)) { + $o->score = 3; + } + } + } + if (count ($files) == 0) + return; + + usort ($files, "cmp"); + $maxscore = $files[0]->score; + + // careful! there may be more than one file per book to scan + + for ($i = 0; $i < count ($files); $i++) { + $o =& $files[$i]; + if ($o->score != $maxscore) { + continue; + } + if (is_link ("$config->filesroot/$o->filename")) { + continue; + } + if (!is_readable ("$config->filesroot/$o->filename")) { + continue; + } + $s = @stat ("$config->filesroot/$o->filename"); + if (!$s) { + continue; + } + + // ok, send it out + echo ("Path-Name: $fk_books/$o->fk_files/$o->fk_filetypes/$o->fk_encodings\n" . + "Content-Length: {$s['size']}\n" . + "Document-Type: $o->type\n\n"); + + readfile ("$config->filesroot/$o->filename"); + } +} + +$db->exec ("select pk from books order by pk"); + +if ($db->FirstRow ()) { + do { + $fk_books = $db->get ("pk", SQLINT); + book ($fk_books); + } while ($db->NextRow ()); +} + +?> diff --git a/catalog/admin/tail.php b/catalog/admin/tail.php new file mode 100644 index 0000000..1314807 --- /dev/null +++ b/catalog/admin/tail.php @@ -0,0 +1,17 @@ + diff --git a/catalog/admin/tail.php~ b/catalog/admin/tail.php~ new file mode 100644 index 0000000..1a2216c --- /dev/null +++ b/catalog/admin/tail.php~ @@ -0,0 +1,16 @@ + diff --git a/catalog/admin/title-checker.php b/catalog/admin/title-checker.php new file mode 100644 index 0000000..f524455 --- /dev/null +++ b/catalog/admin/title-checker.php @@ -0,0 +1,68 @@ +db (); +$db2 = $config->db (); + +$pks = array (); +$gutindex = array (); + +$db->exec ("select * from titles where title_order = 1 order by fk_books"); + +if ($db->FirstRow ()) { + do { + $pk = $db->get ("pk", SQLINT); + $fk_books = $db->get ("fk_books", SQLINT); + $title = $db->get ("title", SQLCHAR); + + $db2->exec ("select gutindex from books where pk = $fk_books"); + $gutindex = $db2->get ("gutindex", SQLCHAR); + + if (empty ($gutindex)) { + continue; + } + + $gutindex = preg_replace ("/^\w+\s+\d+\s+/", "", $gutindex); + $title = preg_replace ("/\s*—.*/", "", $title); + $title = preg_replace ("/\s*--.*/", "", $title); + + $s = array ('The ', 'A ', 'An '); + $r = array ('', '', ''); + + $gutindex = str_replace ($s, $r, $gutindex); + $title = str_replace ($s, $r, $title); + + + if (!strncasecmp ($title, $gutindex, strlen ($title))) continue; + + $t = strtr ($title, ",.:;-_'", " "); + $awords = preg_split ("/\s+/", $t); + + $i = 0; + $words = 0; + $matched = 0; + + foreach ($awords as $word) { + if (strlen ($word) >= 5) { + if (!strncasecmp ($word, "Vol", 3)) continue; + if ($word == "Part") continue; + $words++; + if (strpos ($gutindex, $word) !== false) { + $matched++; + } + } + $i++; + } + if ($matched < 1) { + echo ("$fk_books\n\n$title\n\n$gutindex\n\n----------\n\n"); + } + } while ($db->NextRow ()); +} + + +?> diff --git a/catalog/admin/title-checker.php~ b/catalog/admin/title-checker.php~ new file mode 100644 index 0000000..2058014 --- /dev/null +++ b/catalog/admin/title-checker.php~ @@ -0,0 +1,67 @@ +db (); +$db2 = $config->db (); + +$pks = array (); +$gutindex = array (); + +$db->exec ("select * from titles where title_order = 1 order by fk_books"); + +if ($db->FirstRow ()) { + do { + $pk = $db->get ("pk", SQLINT); + $fk_books = $db->get ("fk_books", SQLINT); + $title = $db->get ("title", SQLCHAR); + + $db2->exec ("select gutindex from books where pk = $fk_books"); + $gutindex = $db2->get ("gutindex", SQLCHAR); + + if (empty ($gutindex)) { + continue; + } + + $gutindex = preg_replace ("/^\w+\s+\d+\s+/", "", $gutindex); + $title = preg_replace ("/\s*—.*/", "", $title); + $title = preg_replace ("/\s*--.*/", "", $title); + + $s = array ('The ', 'A ', 'An '); + $r = array ('', '', ''); + + $gutindex = str_replace ($s, $r, $gutindex); + $title = str_replace ($s, $r, $title); + + + if (!strncasecmp ($title, $gutindex, strlen ($title))) continue; + + $t = strtr ($title, ",.:;-_'", " "); + $awords = preg_split ("/\s+/", $t); + + $i = 0; + $words = 0; + $matched = 0; + + foreach ($awords as $word) { + if (strlen ($word) >= 5) { + if (!strncasecmp ($word, "Vol", 3)) continue; + if ($word == "Part") continue; + $words++; + if (strpos ($gutindex, $word) !== false) { + $matched++; + } + } + $i++; + } + if ($matched < 1) { + echo ("$fk_books\n\n$title\n\n$gutindex\n\n----------\n\n"); + } + } while ($db->NextRow ()); +} + + +?> \ No newline at end of file diff --git a/catalog/admin/titles.php b/catalog/admin/titles.php new file mode 100644 index 0000000..f3982ef --- /dev/null +++ b/catalog/admin/titles.php @@ -0,0 +1,91 @@ +db (); +getstr ("titlemask"); +getint ("maxcnt", 25); + +pageheader ("Batch-Edit Attributes"); + +$marcs = array (); + +$db->exec ("select * from attriblist order by pk"); +if ($db->FirstRow ()) { + do { + $marcs[$db->get ("pk", SQLINT)] = $db->get ("name", SQLCHAR); + } while ($db->NextRow ()); +} + +function mk_options ($name, $options, $option) { + $ret = ""; + foreach ($options as $value => $opt) { + $selected = ($value == $option) ? " selected=\"selected\"" : ""; + $ret .= "\n"; + } + return "\n"; +} + +class TypeColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Type", "narrow"); + } + function Data ($db) { + global $marcs; + return "" . mk_options ("marcs", $marcs, $db->get ("fk_attriblist")) . ""; + } +} + +class TextAreaColumn extends dbtSimpleColumn { + function __construct ($dbfield, $caption, $class = null) { + parent::__construct ($dbfield, $caption, $class); + } + function Data ($db) { + global $config; + return "" . preg_replace ("/#(\w+)#/e", + "htmlspecialchars (\$db->get('\\1'))", $this->dbfield) . ""; + } +} + + +form_open_get (); +p ("Enter Perl RegExp: + eg. Commedia"); +p ("Max. No.: "); +form_submit ("Reload"); +form_close (); + +$t = new ListTable (); +$t->AddColumn ("", "", "narrow"); +$t->AddColumn ("", "Nonfiling"); +$t->AddColumnObject (new TextAreaColumn ("" . + "", "Title")); +$t->AddColumnObject (new TypeColumn ()); +$t->AddColumn ("etext/#fk_books#\">#fk_books#", "eBook"); + +///////////////////////////////////////////////////////////////////////////////// + +if (!empty ($titlemask)) { + form_open ("titles2"); + $sql = "select * from attributes where text ~ '$titlemask' order by text"; + $db->exec ($sql); + $t->limit = $maxcnt; + $t->PrintTable ($db, "Attributes Matching RegExp: $titlemask", "pgdbfiles"); + form_relay ("titlemask"); + form_relay ("maxcnt"); + form_submit ("Update Checked Attribute Entries"); + form_close (); +} + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/titles.php~ b/catalog/admin/titles.php~ new file mode 100644 index 0000000..37def11 --- /dev/null +++ b/catalog/admin/titles.php~ @@ -0,0 +1,90 @@ +db (); +getstr ("titlemask"); +getint ("maxcnt", 25); + +pageheader ("Batch-Edit Attributes"); + +$marcs = array (); + +$db->exec ("select * from attriblist order by pk"); +if ($db->FirstRow ()) { + do { + $marcs[$db->get ("pk", SQLINT)] = $db->get ("name", SQLCHAR); + } while ($db->NextRow ()); +} + +function mk_options ($name, $options, $option) { + $ret = ""; + foreach ($options as $value => $opt) { + $selected = ($value == $option) ? " selected=\"selected\"" : ""; + $ret .= "\n"; + } + return "\n"; +} + +class TypeColumn extends dbtSimpleColumn { + function __construct () { + parent::__construct (null, "Type", "narrow"); + } + function Data ($db) { + global $marcs; + return "" . mk_options ("marcs", $marcs, $db->get ("fk_attriblist")) . ""; + } +} + +class TextAreaColumn extends dbtSimpleColumn { + function __construct ($dbfield, $caption, $class = null) { + parent::__construct ($dbfield, $caption, $class); + } + function Data ($db) { + global $config; + return "" . preg_replace ("/#(\w+)#/e", + "htmlspecialchars (\$db->get('\\1'))", $this->dbfield) . ""; + } +} + + +form_open_get (); +p ("Enter Perl RegExp: + eg. Commedia"); +p ("Max. No.: "); +form_submit ("Reload"); +form_close (); + +$t = new ListTable (); +$t->AddColumn ("", "", "narrow"); +$t->AddColumn ("", "Nonfiling"); +$t->AddColumnObject (new TextAreaColumn ("" . + "", "Title")); +$t->AddColumnObject (new TypeColumn ()); +$t->AddColumn ("etext/#fk_books#\">#fk_books#", "eBook"); + +///////////////////////////////////////////////////////////////////////////////// + +if (!empty ($titlemask)) { + form_open ("titles2"); + $sql = "select * from attributes where text ~ '$titlemask' order by text"; + $db->exec ($sql); + $t->limit = $maxcnt; + $t->PrintTable ($db, "Attributes Matching RegExp: $titlemask", "pgdbfiles"); + form_relay ("titlemask"); + form_relay ("maxcnt"); + form_submit ("Update Checked Attribute Entries"); + form_close (); +} + +pagefooter (); + +// Local Variables: +// mode:php +// coding:utf-8-unix +// fill-column: 75 +// End: + +?> diff --git a/catalog/admin/titles2.php b/catalog/admin/titles2.php new file mode 100644 index 0000000..2420046 --- /dev/null +++ b/catalog/admin/titles2.php @@ -0,0 +1,55 @@ +db (); +$db->logger = new logger (); + +getstr ("titlemask"); +getint ("maxcnt"); + +getarray ("pks_update"); +getarray ("pks"); + +getarray ("titles_a"); +getarray ("nonfilings"); +getarray ("marcs"); + +foreach ($pks as $pk) { + $title = array_shift ($titles_a); + $nonfiling = array_shift ($nonfilings); + $marc = array_shift ($marcs); + + if (!in_array ($pk, $pks_update)) + continue; + + $sql_pk = $db->f ($pk, SQLINT); + $sql_title = $db->f ($title, SQLCHAR); + $sql_nonfiling = $db->f ($nonfiling, SQLINT); + $sql_marc = $db->f ($marc, SQLINT); + + $sql = "update attributes set " . + "text = $sql_title, " . + "nonfiling = $sql_nonfiling, " . + "fk_attriblist = $sql_marc " . + "where pk = $sql_pk"; + + p ($sql); + + if ($db->exec ($sql)) { + msg ("Attribute '$title' updated !"); + } else { + error_msg ("Could not update attribute '$title' !"); + } +} + +p ("Back to Batch-Edit Attributes"); + +pagefooter (); + +?> diff --git a/catalog/admin/titles2.php~ b/catalog/admin/titles2.php~ new file mode 100644 index 0000000..41f2987 --- /dev/null +++ b/catalog/admin/titles2.php~ @@ -0,0 +1,54 @@ +db (); +$db->logger = new logger (); + +getstr ("titlemask"); +getint ("maxcnt"); + +getarray ("pks_update"); +getarray ("pks"); + +getarray ("titles_a"); +getarray ("nonfilings"); +getarray ("marcs"); + +foreach ($pks as $pk) { + $title = array_shift ($titles_a); + $nonfiling = array_shift ($nonfilings); + $marc = array_shift ($marcs); + + if (!in_array ($pk, $pks_update)) + continue; + + $sql_pk = $db->f ($pk, SQLINT); + $sql_title = $db->f ($title, SQLCHAR); + $sql_nonfiling = $db->f ($nonfiling, SQLINT); + $sql_marc = $db->f ($marc, SQLINT); + + $sql = "update attributes set " . + "text = $sql_title, " . + "nonfiling = $sql_nonfiling, " . + "fk_attriblist = $sql_marc " . + "where pk = $sql_pk"; + + p ($sql); + + if ($db->exec ($sql)) { + msg ("Attribute '$title' updated !"); + } else { + error_msg ("Could not update attribute '$title' !"); + } +} + +p ("Back to Batch-Edit Attributes"); + +pagefooter (); + +?> diff --git a/catalog/admin/unzip b/catalog/admin/unzip new file mode 100755 index 0000000..3791314 Binary files /dev/null and b/catalog/admin/unzip differ diff --git a/catalog/admin/user.php b/catalog/admin/user.php new file mode 100644 index 0000000..9c88027 --- /dev/null +++ b/catalog/admin/user.php @@ -0,0 +1,76 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_users"); +getstr ("filter"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this user."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("user", "user", "User", SQLCHAR, 80, 240, true); + $f->Text ("login", "login", "Login", SQLCHAR, 80, 240, true); + $f->TextArea ("note", "note", "Note", SQLCHAR, 4, 80, false); + + $f->LoadData ("select * from users where pk = $fk_users"); +} +$f->Hidden ("fk_users"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into users " . $sql)) { + msg ("User added !"); + } else { + error_msg ("Could not add user!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update users set " . $sql . "where pk = $fk_users")) { + msg ("User modified !"); + } else { + error_msg ("Could not modify user !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_users_permissions where fk_users = $fk_users"); + if ($db->Exec ("delete from users where pk = $fk_users")) { + msg ("User deleted !"); + } else { + error_msg ("Could not delete user !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + p ("Back to User"); + } +} else { + $f->Output ($caption, $caption); +} + +p ("Back to User List"); + +pagefooter (); + +?> diff --git a/catalog/admin/user.php~ b/catalog/admin/user.php~ new file mode 100644 index 0000000..aba9376 --- /dev/null +++ b/catalog/admin/user.php~ @@ -0,0 +1,75 @@ +db (); +$db->logger = new logger (); +$f = new SQLForm (); +getint ("fk_users"); +getstr ("filter"); + +if (ismode ("delete")) { + $f->SubCaption ("You are about to delete this user."); + $f->SubCaption ("Press the '$caption' button to continue or " . + "hit the back button on your browser to dismiss."); +} else { + $f->Text ("user", "user", "User", SQLCHAR, 80, 240, true); + $f->Text ("login", "login", "Login", SQLCHAR, 80, 240, true); + $f->TextArea ("note", "note", "Note", SQLCHAR, 4, 80, false); + + $f->LoadData ("select * from users where pk = $fk_users"); +} +$f->Hidden ("fk_users"); +$f->Hidden ("filter"); + +if (isupdatemode ("add")) { + if ($f->Check ()) { + $sql = $f->mkInsert ($db->GetFormatter ()); + if ($db->Exec ("insert into users " . $sql)) { + msg ("User added !"); + } else { + error_msg ("Could not add user!"); + } + } +} +if (isupdatemode ("edit")) { + if ($f->Check ()) { + $sql = $f->mkUpdate ($db->GetFormatter ()); + if ($db->Exec ("update users set " . $sql . "where pk = $fk_users")) { + msg ("User modified !"); + } else { + error_msg ("Could not modify user !"); + } + } +} +if (isupdatemode ("delete")) { + $db->Exec ("delete from mn_users_permissions where fk_users = $fk_users"); + if ($db->Exec ("delete from users where pk = $fk_users")) { + msg ("User deleted !"); + } else { + error_msg ("Could not delete user !"); + } +} + +if (isupdate ()) { + if (!isupdatemode ("delete")) { + p ("Back to User"); + } +} else { + $f->Output ($caption, $caption); +} + +p ("Back to User List"); + +pagefooter (); + +?> diff --git a/catalog/admin/users_list.php b/catalog/admin/users_list.php new file mode 100644 index 0000000..35d0f6f --- /dev/null +++ b/catalog/admin/users_list.php @@ -0,0 +1,48 @@ +AddColumn ("$prefix=edit&fk_users=#pk#\">Edit", "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_users=#pk#\">Delete", "", "narrow"); + $this->AddColumn ("Password", "", "narrow"); + $this->AddSimpleColumn ("pk", "Id", "narrow"); + $this->AddSimpleColumn ("user", "User"); + $this->AddSimpleColumn ("login", "Login"); + $this->AddSimpleColumn ("password", "Password"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the user name (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. Marcello*) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from users where user like '$filt%' order by user;"); + $table = new ListUsersTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/users_list.php~ b/catalog/admin/users_list.php~ new file mode 100644 index 0000000..c07c0a8 --- /dev/null +++ b/catalog/admin/users_list.php~ @@ -0,0 +1,47 @@ +AddColumn ("$prefix=edit&fk_users=#pk#\">Edit", "$prefix=add\">Add", "narrow"); + $this->AddColumn ("$prefix=delete&fk_users=#pk#\">Delete", "", "narrow"); + $this->AddColumn ("Password", "", "narrow"); + $this->AddSimpleColumn ("pk", "Id", "narrow"); + $this->AddSimpleColumn ("user", "User"); + $this->AddSimpleColumn ("login", "Login"); + $this->AddSimpleColumn ("password", "Password"); + } +} + +$db = $config->db (); + +echo (" +

Please enter the first few characters of the user name (at least one). +Search is case-sensitive. +Use * as wildcard. (eg. Marcello*) +To see everything just enter *.

+"); + +form_open (); +echo (" \n"); +form_submit ("Search"); +form_close (); + +if ($filter != "") { + $filt = preg_replace ('/\*/', '%', $filter); + $db->exec ("select * from users where user like '$filt%' order by user;"); + $table = new ListUsersTable (); + $table->PrintTable ($db, $caption); +} + +pagefooter (); + +?> diff --git a/catalog/admin/whois.php b/catalog/admin/whois.php new file mode 100644 index 0000000..db14724 --- /dev/null +++ b/catalog/admin/whois.php @@ -0,0 +1,20 @@ +\n"); + +echo `whois $ip`; + +echo ("\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/whois.php~ b/catalog/admin/whois.php~ new file mode 100644 index 0000000..627ee4f --- /dev/null +++ b/catalog/admin/whois.php~ @@ -0,0 +1,19 @@ +\n"); + +echo `whois $ip`; + +echo ("\n"); + +pagefooter (); + +?> diff --git a/catalog/admin/zipdir.php b/catalog/admin/zipdir.php new file mode 100644 index 0000000..ad70f45 --- /dev/null +++ b/catalog/admin/zipdir.php @@ -0,0 +1,59 @@ +\n" . shell_exec ("./unzip -lv $file") . "\n\n"); + +/* +class ZipdirTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("", "Filename"); + $this->AddSimpleColumn ("", "Original Size"); + $this->AddSimpleColumn ("", "Compressed Size"); + $this->AddSimpleColumn ("", "Compression Method"); + $this->limit = -1; + } +} + +$array = array (); + +$zip = zip_open ($file); + +if ($zip) { + while ($zip_entry = zip_read ($zip)) { + $array[] = zip_entry_name ($zip_entry); + $array[] = zip_entry_filesize ($zip_entry); + $array[] = zip_entry_compressedsize ($zip_entry); + $array[] = zip_entry_compressionmethod ($zip_entry); + } + zip_close($zip); +} + +$table = new ZipdirTable (); +$table->summary = "Contents of zip file."; +$table->toprows = $array; +$table->PrintTable (null, "Zip Directory"); +*/ + +pagefooter (); + +?> diff --git a/catalog/admin/zipdir.php~ b/catalog/admin/zipdir.php~ new file mode 100644 index 0000000..55a3828 --- /dev/null +++ b/catalog/admin/zipdir.php~ @@ -0,0 +1,58 @@ +\n" . shell_exec ("./unzip -lv $file") . "\n\n"); + +/* +class ZipdirTable extends ListTable { + function __construct () { + $this->AddSimpleColumn ("", "Filename"); + $this->AddSimpleColumn ("", "Original Size"); + $this->AddSimpleColumn ("", "Compressed Size"); + $this->AddSimpleColumn ("", "Compression Method"); + $this->limit = -1; + } +} + +$array = array (); + +$zip = zip_open ($file); + +if ($zip) { + while ($zip_entry = zip_read ($zip)) { + $array[] = zip_entry_name ($zip_entry); + $array[] = zip_entry_filesize ($zip_entry); + $array[] = zip_entry_compressedsize ($zip_entry); + $array[] = zip_entry_compressionmethod ($zip_entry); + } + zip_close($zip); +} + +$table = new ZipdirTable (); +$table->summary = "Contents of zip file."; +$table->toprows = $array; +$table->PrintTable (null, "Zip Directory"); +*/ + +pagefooter (); + +?> diff --git a/catalog/index.md b/catalog/index.md new file mode 100644 index 0000000..aaf7ac9 --- /dev/null +++ b/catalog/index.md @@ -0,0 +1,12 @@ +--- +layout: default +title: Online Book Catalog | Project Gutenberg +permalink: /catalog/index.html +--- + +Page not correct +================ + +This is the old address for searching. + +Please instead use the new location: [book search](/ebooks). diff --git a/catalog/osd-books.xml b/catalog/osd-books.xml new file mode 100644 index 0000000..ec6c3fc --- /dev/null +++ b/catalog/osd-books.xml @@ -0,0 +1,36 @@ + + + + Project Gutenberg + Gutenberg + Search the Project Gutenberg ebook catalog. + free ebooks books public domain + Marcello Perathoner + webmaster@gutenberg.org + + + + + + + + + + + + + Search Data Copyright 1971-2012, Project Gutenberg, All Rights Reserved. + open + en-us + UTF-8 + UTF-8 + diff --git a/catalog/test_index.php b/catalog/test_index.php new file mode 100644 index 0000000..fdcd632 --- /dev/null +++ b/catalog/test_index.php @@ -0,0 +1,10 @@ +

Testing php

+ +

Phpinfo output:

+ + +

Output ends.

+ + diff --git a/catalog/test_index.php~ b/catalog/test_index.php~ new file mode 100644 index 0000000..87a4b70 --- /dev/null +++ b/catalog/test_index.php~ @@ -0,0 +1,17 @@ +--- +layout: default +title: Free eBooks | Project Gutenberg +permalink: /test_index.html +--- + +Testing php +=========== + +Phpinfo output: + + +Output ends. + +