diff options
-rw-r--r-- | portdb/portdb/footer.html | 5 | ||||
-rw-r--r-- | portdb/portdb/header.html | 29 | ||||
-rwxr-xr-x | portdb/portdb/index.php | 609 | ||||
-rw-r--r-- | portdb/portdb/opensearch.xml | 15 | ||||
-rw-r--r-- | portdb/portdb/register.html | 9 |
5 files changed, 470 insertions, 197 deletions
diff --git a/portdb/portdb/footer.html b/portdb/portdb/footer.html new file mode 100644 index 0000000..7e9de66 --- /dev/null +++ b/portdb/portdb/footer.html @@ -0,0 +1,5 @@ +</div> +<div class="footer"> + <b>DISCLAIMER</b>: the ports not belonging to the core, opt and xorg collections are provided by contributors; there is no guarantee or support by the CRUX team. +</div> +</body></html> diff --git a/portdb/portdb/header.html b/portdb/portdb/header.html new file mode 100644 index 0000000..fcd60df --- /dev/null +++ b/portdb/portdb/header.html @@ -0,0 +1,29 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>CRUX port browser</title> + <link rel="stylesheet" type="text/css" href="portdb.css"/> + <link rel="search" type="application/opensearchdescription+xml" href="opensearch.xml" title="CRUX portdb search"/> + </head> + <body> + <div class="cruxheader"> + <a href="/" title="">Home</a> :: + <a href="/Main/Documentation">Documentation</a> :: + <a href="/Main/Download">Download</a> :: + <a href="/Main/Development">Development</a> :: + <a href="/Main/Community">Community</a> :: + <a href="/Wiki/HomePage">Wiki</a> :: + <a href="/portdb">Ports</a> :: + <a href="/Main/Bugs" title="">Bugs</a> :: + <a href="/Main/Links" title="">Links</a> :: + <a href="/Main/About" title="">About</a> + </div> + <form method="get" action="/portdb/" enctype="application/x-www-form-urlencoded"> + <div class="search"> + <input type="hidden" name="a" value="search" /> + search ports: + <input type="text" name="q" size="10" /> + </div> + </form> + <div class="content"> + <b>Sections: </b><a href="?a=index">Repositories</a> :: <a href="?a=search">Search</a> :: <a href="?a=register">Register</a> :: <a href="?a=dups">Duplicates</a> diff --git a/portdb/portdb/index.php b/portdb/portdb/index.php index 54496b0..4d14d37 100755 --- a/portdb/portdb/index.php +++ b/portdb/portdb/index.php @@ -1,231 +1,446 @@ <?php + require('DB.php'); -# Mini port repostory browser -# Written by Simone Rota <sip@crux.nu> -$dsn = 'sqlite:////home/crux/public_html/local/portdb.db'; +$dbhandle = "sqlite:////home/crux/public_html/local/portdb.db"; + +function nospam($mail) { + $mail = preg_replace("/\@/", " at ", $mail); + $mail = preg_replace("/\./", " dot ", $mail); + return htmlspecialchars($mail); +} function sanitize($str) { - return $str; -} + return $str; +} -function nospam($mail) { - $mail = preg_replace("/\@/", " at ", $mail); - $mail = preg_replace("/\./", " dot ", $mail); - return htmlspecialchars($mail); +class Repo +{ + public $name; + public $maintainer; + public $type; + public $url; + public $count; + + function __construct($row) { + $this->name = trim($row["collname"]); + $this->maintainer = trim($row["maintainer"]); + $this->type = trim($row["colltype"]); + $this->url = trim($row["url"]); + $this->count = trim($row["tot"]); + } + + function toHTML() { + return "<td><a href=\"?a=repo&q={$this->name}\">{$this->name}</a></td> + <td>{$this->count}</td> + <td><a href=\"?a=getup&q={$this->name}\">{$this->type}</a></td> + <td>{$this->nospam()}</td> + <td>{$this->urlToHTML()}</td>"; + } + + function toXML() { + return "<repo> + <name>{$this->name}</name> + <maintainer>{$this->nospam()}</maintainer> + <type>{$this->type}</type> + <url>{$this->url}</url> + <ports>{$this->count}</ports> + </repo>"; + } + + function urlToHTML() { + if ($this->type == "httpup") { + return "<a href=\"{$this->url}\">{$this->url}</a>"; + } + else { + return $this->url; + } + } + + function nospam() { + return nospam($this->maintainer); + } } -function printHeader() { - echo ' - <html> - <head> - <title>CRUX port browser</title> - <link rel="stylesheet" type="text/css" href="portdb.css"/> - </head> - <body> - <div class="cruxheader"> - <a href="/" title="">Home</a> :: - <a href="/Main/Documentation">Documentation</a> :: - <a href="/Main/Download">Download</a> :: - <a href="/Main/Development">Development</a> :: - <a href="/Main/Community">Community</a> :: - <a href="/Wiki/HomePage">Wiki</a> :: - <a href="/portdb">Ports</a> :: - <a href="/Main/Bugs" title="">Bugs</a> :: - <a href="/Main/Links" title="">Links</a> :: - <a href="/Main/About" title="">About</a> - </div> - <form method="get" action="/portdb/" enctype="application/x-www-form-urlencoded"> - <div class="search"> - <input type="hidden" name="a" value="search" /> - search ports: - <input type="text" name="q" size="10" /> - </div> - </form> - '; +class Port +{ + public $name; + public $repo; + + function __construct($row) { + $this->name = trim($row["portname"]); + $this->repo = new Repo($row); + } + + function toXML() { + return "<port> + <name>{$this->name}</name> + <repo>{$this->repo->name}</repo> + {$this->filesToXML()} + <command>{$this->downloadCommand()}</command> + </port>"; + + } + + function toHTML() { + return "<td>{$this->name}</td> + <td><a href=\"?a=repo&q={$this->repo->name}\">{$this->repo->name}</a></td> + <td>{$this->filesToHTML()}</td> + <td>{$this->downloadCommand()}</td>"; + } + + function filesToXML() { + $xml = ""; + if ($this->repo->type == "httpup") { + $base_url = "{$this->repo->url}/{$this->name}/"; + $xml = "<files>"; + $xml .= "<pkgfile>{$base_url}Pkgfile</pkgfile>"; + $xml .= "<footprint>{$base_url}.footprint</footprint>"; + $xml .= "<md5sum>{$base_url}.md5sum</md5sum>"; + $xml .= "</files>"; + } + return $xml; + } + + function filesToHTML() { + $html = ""; + if ($this->repo->type == "httpup") { + $base_url = "{$this->repo->url}/{$this->name}/"; + $html = "<a href=\"{$base_url}Pkgfile\">P</a> "; + $html .= "<a href=\"{$base_url}.footprint\">F</a> "; + $html .= "<a href=\"{$base_url}.md5sum\">M</a>"; + } + return $html; + } + + function downloadCommand() { + switch ($this->repo->type) { + case "httpup": + return "httpup sync {$this->repo->url}#{$this->name} {$this->name}"; + case "rsync": + return "rsync -aqz {$this->repo->url}{$this->name}/ {$this->name}"; + default: + return "unknown repo type"; + } + } } -function printFooter() { - echo '</div><div class="footer"><b>DISCLAIMER</b>: the ports not belonging to the core and opt collections are provided by contributors; there is no guarantee or support by the CRUX team.</div></body></html>'; +class Duplicate +{ + public $name; + public $count; + + function __construct($row) { + $this->name = $row["portname"]; + $this->count = $row["dup"]; + } + + function toHTML() { + return "<td>{$this->name}</td> + <td>Found <a href=\"?a=search&q={$this->name}&s=true\">{$this->count} in repository</a></td>"; + } + + function toXML() { + return "<duplicate> + <name>{$this->name}</name> + <count>{$this->count}</count> + </duplicate>"; + } } -function printNav() { - echo '<div class="content"><b>Sections: </b><a href="?a=index">Repositories</a> :: <a href="?a=register">Register</a> :: <a href="?a=dups">Duplicates</a>'; +class PortDb +{ + public $db; + public $last_result; + + function __construct($dbhandle) { + $this->db =& DB::connect($dbhandle); + if (DB::isError($this->db)) die ("Can not connect to database"); + $this->db->setFetchMode(DB_FETCHMODE_ASSOC); + } + + function lazy_programmer() { + die("LAZY PROGRAMMER ERROR"); + } + + function getQuery() { + try { + $sth = $this->db->prepare($this->sql); + $args = func_get_args(); + $res = $this->db->execute($sth, $args); + if (DB::isError($res)) die ($res->getUserInfo()); + $this->last_result = array(); + while ($row =& $res->fetchRow()) { + array_push($this->last_result, $row); + } + return $this->last_result; + } + catch (Exception $exception) { + die($exception->getMessage()); + } + } + + function doQuery() { + $this->lazy_programmer(); + } + + function htmlHeader() { + return file_get_contents("header.html"); + } + + function htmlFooter() { + return file_get_contents("footer.html"); + } + + function toHTML($start, $headers, $items) { + $html = $this->htmlHeader(); + $html .= $start; + $html .= "<table class=\"listing\">"; + $html .= "<thead><tr>"; + foreach ($headers as $header) { + $html .= "<th>{$header}</th>"; + } + $html .= "</tr></thead>"; + foreach ($items as $item) { + $html .= "<tr>" . $item->toHTML() . "</tr>"; + } + $html .= "</table>"; + $html .= $this->htmlFooter(); + return $html; + } + + function toXML($root, $items) { + header("Content-type: text/xml"); + $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; + $xml .= "<{$root}>"; + foreach ($items as $item) { + $xml .= $item->toXML(); + } + $xml .= "</{$root}>"; + return $xml; + } +} + +class RepoList extends PortDb +{ + public $sql = 'select collname,maintainer,colltype,url,count(*) as tot from collections + join ports on collection=collname + group by collname order by collections.collid'; + + function doQuery() { + $rows = $this->getQuery(); + $repos = array(); + foreach($rows as $row) { + $repo = new Repo($row); + array_push($repos, $repo); + } + return $repos; + } + + function toXML($repos) { + return parent::toXML("repos", $repos); + } + + function toHTML($repos) { + $start = "<h2>Overview of available repositories</h2>"; + $headers = array("Repo Name", "# ports", "Type", "Maintainer", "Repo URL"); + return parent::toHtml($start, $headers, $repos); + } } -function showCollections() { - global $db; - $sql = "select collname,maintainer,colltype,url,count(*) as tot from collections - join ports on collection=collname - group by collname order by collections.collid"; - $res =& $db->Query($sql); - if (DB::isError($res)) die("Query error"); - echo "<h2>Overview of available repositories</h2>\n"; - echo '<table class="listing">'; - echo '<thead><tr><th>Repo Name</th><th># ports</th><th>Type</th><th>Maintainer</th><th>Repo URL</th></tr></thead>'; - $i=0; - while ($repo =& $res->fetchRow()) { - $cl = "row".$i%2; - echo '<tr class="'.$cl.'"> - <td><a href="?a=repo&q='.$repo['collname'].'">'.$repo['collname'].'</a></td> - <td>'.$repo['tot'].'</td> - <td><a href="?a=getup&q='.$repo['collname'].'">'.$repo['colltype'].'</a></td> - <td>'.nospam($repo['maintainer']).'</td>'; - if ($repo['colltype'] == "httpup") { - echo '<td><a href="'.$repo['url'].'">'.$repo['url'].'</a></td></tr>'; - } else { - echo '<td>'.$repo['url'].'</td></tr>'; - } - $i++; - } - echo "</table>"; - +class PortList extends PortDb +{ + public $sql = "select ports.portname as portname, + collections.collname as collname, + collections.maintainer as maintainer, + collections.colltype as colltype, + collections.url as url + from ports join collections on collection=collname + where collection = ? order by portname"; + + function doQuery($repo) { + $rows = $this->getQuery($repo); + $ports = array(); + foreach ($rows as $row) { + $port = new Port($row); + array_push($ports, $port); + } + return $ports; + } + + function toXML($ports) { + return parent::toXML("ports", $ports); + } + + function toHTML($ports) { + $repo = $ports[0]->repo->name; + $start = "<h2>Ports in repository $repo <a href=\"?a=getup&q={$repo}\">(get sync file)</a></h2>"; + $headers = array("Port","Collection","Files","Download command"); + return parent::toHTML($start, $headers, $ports); + } } -function showSearch($singlerepo) { - global $db; - $query = sanitize($_GET['q']); - $strict = sanitize($_GET['s']); - if ($query == "") { - echo '<h2>Simple port search</h2> +class SearchList extends PortList +{ + public $strict = false; + public $query = ''; + public $sql; + + function __construct($dbhandle, $strict) { + parent::__construct($dbhandle); + if ($strict == "true") $this->strict = true; + $sql = "select ports.portname as portname, + collections.collname as collname, + collections.maintainer as maintainer, + collections.colltype as colltype, + collections.url as url + from ports join collections on collection=collname "; + if ($this->strict) { + $this->sql = $sql . "where portname=? "; + } + else { + $this->sql = $sql . "where portname like ? "; + } + $this->sql .= "order by portname, collection"; + } + + function htmlHeader() { + $html = parent::htmlHeader(); + $html .= '<h2>Simple port search</h2> <p>Search for ports by name</p> - <form name="searchform" method="get"> - <input name="q" value=""> - <input type=hidden name="a" value="search"> - <input value="search" type="submit"> - </form>'; - } else { - if ($singlerepo) { - echo "<h2>Ports in repository '$query'".' (<a href="?a=getup&q='.$query.'">get httpup/rsync</a>)'."</h2>"; - $sql = "select * from ports join collections on collection=collname - where collection = ? order by portname"; - } else { - echo "<h2>Search results for '$query'</h2>"; - if ($strict === "true") { - $sql = "select * from ports join collections on collection=collname - where portname=? order by portname, collection"; - } else { - $query = "%".$query."%"; - $sql = "select * from ports join collections on collection=collname - where portname like ? order by portname, collection"; - } - } - $sth = $db->prepare($sql); - $res = $db->execute($sth, array($query)); - if (DB::isError($res)) die($res->getDebugInfo());#die("Query error (search)"); - echo "\n<table class=\"listing\"><thead><tr><th>Port</th><th>Collection</th><th>Files</th><th>Download command</th>\n</tr></thead>\n"; - $i = 0; - while ($port =& $res->fetchRow()) { - $cl = "row".$i%2; - echo '<tr class="'.$cl.'"> - <td>'.$port['ports.portname'].'</td> - <td><a href="?a=repo&q='.$port['collections.collname'].'">'.$port['collections.collname']."</a></td>\n"; - if ($port['collections.colltype'] == "httpup") { - echo '<td><a href="'.$port['collections.url'].$port['ports.portname'].'/Pkgfile">P</a> '."\n"; - echo '<a href="'.$port['collections.url'].$port['ports.portname'].'/.footprint">F</a> '."\n"; - echo '<a href="'.$port['collections.url'].$port['ports.portname'].'/.md5sum">M</a></td>'."\n"; - echo '<td>httpup sync '.trim($port['collections.url'],"/")."#".$port['ports.portname']." ".$port['ports.portname'] .'</td>'."\n"; - } else { - echo '<td>-</td>'."\n"; - echo '<td>rsync -aqz '.$port['collections.url'].$port['ports.portname']."/ ".$port['ports.portname'] .'</td>'."\n"; - } - echo "</tr>\n"; - $i++; - } - echo "</table>"; + <form name="searchform" method="get" action="'.getenv("SCRIPT_NAME").'"> + <input name="q" value="'.$this->query.'" /> + <input type="hidden" name="a" value="search" /> + <input value="search" type="submit" /> + </form>'; + return $html; + } + + function doQuery($query) { + $this->query = $query; + if ($query) { + if (! $this->strict) $query = "%{$query}%"; + return parent::doQuery($query); + } + return array(); + } + + function toHTML($ports) { + if ($this->query) { + $start = ""; #<h2>Search results for '{$this->query}'</h2>"; + $headers = array("Port","Collection","Files","Download command"); + return PortDb::toHTML($start, $headers, $ports); } + return $this->htmlHeader() . $this->htmlFooter(); + } } -function showRegister() { - $query = sanitize($_GET['q']); - echo "<h2>Register your ports repository</h2>"; - echo "<p>You can register your personal HttpUp repository sending an email with the following information to <i>contrib-admin at crux dot nu</i>:</p>"; - echo '<ul><li>Repository Name <small>(e.g. myports)</small></li> - <li>Root URL <small>(e.g. http://mypage.se/ports/)</small></li> - <li>Your name</li> - <li>Your Email</li></ul>'; - echo "<p>A CRUX team member will put your repository into our database. Please give us some time to do this. Once it is active it is synced once a day. <b>Please do not submit .httpup files, only the URL for the repository. This means the URL to the repository itself, not portspage or other indexes.</b>"; +class DuplicateList extends PortDb +{ + public $sql = "select portname, count(*) as dup + from ports group by portname + having dup>1 + order by dup desc"; + + function doQuery() { + $rows = $this->getQuery(); + $dups = array(); + foreach ($rows as $row) { + $dup = new Duplicate($row); + array_push($dups, $dup); + } + return $dups; + } + + function toHTML($duplicates) { + $start = "<h2>List of duplicate ports</h2>"; + $headers = array("Port", "# of duplicates"); + return parent::toHTML($start, $headers, $duplicates); + } + + function toXML($duplicates) { + return parent::toXML("duplicates",$duplicates); + } } -function showDuplicates() { - global $db; - $sql = "select portname, count(*) as dup from ports - group by portname - having dup>1 - order by dup desc;"; - $res =& $db->Query($sql); - if (DB::isError($res)) die("Query error"); - echo "<h2>List of duplicate ports</h2>\n"; - echo '<table class="listing">'; - echo '<thead><tr><th>Ports</th><th># of duplicates</th></tr></thead>'; - $i=0; - while ($port =& $res->fetchRow()) { - $cl = "row".$i%2; - echo '<tr class="'.$cl.'"> - <td>'.$port['portname'].'</td> - <td>Found in <a href="?a=search&s=true&q='.$port['portname'].'">'.$port['dup']." repositories</a></td></tr>\n"; - $i++; - } - echo "</table>"; +class RegisterPage +{ + function toHTML() { + return PortDb::htmlHeader() . $this->contents() . PortDb::htmlFooter(); + } + + function contents() { + return file_get_contents("register.html"); + } } -function getUp() { - global $db; - $query = sanitize($_GET['q']); - $sql = "select * from collections where collname=?"; - $sth = $db->prepare($sql); - $res = $db->execute($sth, array($query)); - if (DB::isError($res)) die("Query error"); - if ($res->numRows() != 1) - die("Error generating the file"); - $coll =& $res->fetchRow(); +class GetUp extends PortDb +{ + public $sql = "select collname,maintainer,colltype,url + from collections where collname=?"; + public $repo; + + function doQuery($repo) { + $rows = $this->getQuery($repo); + if (count($rows) != 1) die ("Could not generate file"); + return new Repo($rows[0]); + } + + function toHTML($repo) { header('Content-type: text/plain'); - header('Content-Disposition: attachment; filename="'.$coll['collname'].".".$coll['colltype'].'"'); - echo "# Collection ".$coll['collname'].", by ".nospam($coll['maintainer'])."\n"; - echo "# File generated by the CRUX portdb http://crux.nu/portdb/"."\n\n"; - if ($coll['colltype'] == "httpup") { - echo "ROOT_DIR=/usr/ports/" . $coll['collname']."\n"; - echo "URL=" . $coll['url']."\n"; + header('Content-Disposition: attachment; filename="'.$repo->name.".".$repo->type.'"'); + $html = "# Collection ".$repo->name. ", by ".$repo->nospam()."\n"; + $html .= "# File generated by the CRUX portdb http://crux.nu/portdb/"."\n\n"; + if ($repo->type == "httpup") { + $html .= "ROOT_DIR=/usr/ports/" . $repo->name."\n"; + $html .= "URL=" . $repo->url."\n"; } else { - $ar = explode('::', $coll['url']); - echo "host=" . $ar[0]."\n"; - echo "collection=" . $ar[1]."\n"; - echo "destination=/usr/ports/" . $coll['collname']."\n"; + $ar = explode('::', $repo->url); + $html .= "host=" . $ar[0]."\n"; + $html .= "collection=" . $ar[1]."\n"; + $html .= "destination=/usr/ports/" . $repo->name."\n"; } -} - -$db =& DB::connect($dsn); -if (DB::isError($dbc)) die("Cannot connect to database"); -$db->setFetchMode(DB_FETCHMODE_ASSOC); + return $html; + } -$action = sanitize($_GET['a']); -if ($action == "getup") { - getUp(); - exit(0); + function toXML($repo) { + return $this->toHTML($repo); + } } - -printHeader(); -printNav(); + +$action = sanitize($_GET['a']); +$query = sanitize($_GET['q']); +$format = sanitize($_GET['f']); +$strict = sanitize($_GET['s']); switch ($action) { - case "index": - showCollections(); - break; - case "search": - showSearch(FALSE); - break; - case "repo": - showSearch(TRUE); - break; - case "register": - showRegister(); - break; - case "dups": - showDuplicates(); - break; - default: - showCollections(); +case "repo": + $portdb = new PortList($dbhandle); + break; +case "search": + $portdb = new SearchList($dbhandle,$strict); + break; +case "dups": + $portdb = new DuplicateList($dbhandle); + break; +case "getup": + $portdb = new GetUp($dbhandle); + break; +case "register": + $portdb = new RegisterPage(); + echo $portdb->toHTML(); + exit; +default: + $portdb = new RepoList($dbhandle); } -printFooter(); +$result = $portdb->doQuery($query); + +switch ($format) { +case "xml": + echo $portdb->toXML($result); + break; +default: + echo $portdb->toHTML($result); +} ?> diff --git a/portdb/portdb/opensearch.xml b/portdb/portdb/opensearch.xml new file mode 100644 index 0000000..d414378 --- /dev/null +++ b/portdb/portdb/opensearch.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" + xmlns:moz="http://mozilla.org/2006/browser/search"> + <ShortName>CRUX portdb</ShortName> + <Description>Search for CRUX ports</Description> + <Tags>linux crux portdb ports</Tags> + <Contact>lucas@crux.nu</Contact> + <Url type="text/html" method="GET" template="http://crux.nu/portdb/"> + <Param name="a" value="search"/> + <Param name="q" value="{searchTerms}"/> + </Url> + <LongName>CRUX: PortDB Search</LongName> + <Image height="16" width="16" type="image/png">http://crux.nu/favicon.ico</Image> + <InputEncoding>UTF-8</InputEncoding> + </OpenSearchDescription> diff --git a/portdb/portdb/register.html b/portdb/portdb/register.html new file mode 100644 index 0000000..be3bc2e --- /dev/null +++ b/portdb/portdb/register.html @@ -0,0 +1,9 @@ +<h2>Register your ports repository</h2> +<p>You can register your personal HttpUp repository sending an email with the following information to <i>contrib-admin at crux dot nu</i>:</p> +<ul> + <li>Repository Name <small>(e.g. myports)</small></li> + <li>Root URL <small>(e.g. http://mypage.se/ports/)</small></li> + <li>Your name</li> + <li>Your Email</li> +</ul> +<p>A CRUX team member will put your repository into our database. Please give us some time to do this. Once it is active it is synced once a day. <b>Please do not submit .httpup files, only the URL for the repository. This means the URL to the repository itself, not portspage or other indexes.</b></p> |