summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreliott <eliott@cactuswax.net>2007-10-13 06:05:13 +0200
committerDan McGee <dan@archlinux.org>2008-01-20 06:49:35 +0100
commit5e38e3d3d0eff20f8d46bad67c4944a6a1d92ea4 (patch)
treec23cb38182971c201a4f797bcf3f8fde43787be8
parent0cda12132d5b28b3a10a27bcad56bc823116817b (diff)
downloadaur-5e38e3d3d0eff20f8d46bad67c4944a6a1d92ea4.tar.gz
aur-5e38e3d3d0eff20f8d46bad67c4944a6a1d92ea4.tar.xz
Added AurJSON code.
Added a JSON interface to the aur. This should make it easier for developers to integrate command line utilities and poll against the AUR itself.
-rw-r--r--support/schema/aur-schema.sql1
-rw-r--r--web/html/rpc.php22
-rw-r--r--web/lib/aurjson.class.php145
3 files changed, 168 insertions, 0 deletions
diff --git a/support/schema/aur-schema.sql b/support/schema/aur-schema.sql
index 7e3bf2d3..97828fce 100644
--- a/support/schema/aur-schema.sql
+++ b/support/schema/aur-schema.sql
@@ -125,6 +125,7 @@ CREATE TABLE Packages (
AURMaintainerUID INTEGER UNSIGNED NOT NULL DEFAULT 0, -- TU/Dev
Safe TINYINT UNSIGNED NOT NULL DEFAULT 0, -- verified to be safe?
VerifiedBy INTEGER UNSIGNED NOT NULL DEFAULT 0, -- who verified?
+ FULLTEXT (Name,Description),
PRIMARY KEY (ID),
UNIQUE (Name),
INDEX (CategoryID),
diff --git a/web/html/rpc.php b/web/html/rpc.php
new file mode 100644
index 00000000..30813912
--- /dev/null
+++ b/web/html/rpc.php
@@ -0,0 +1,22 @@
+<?php
+
+set_include_path(get_include_path() . PATH_SEPARATOR . '../lib' . PATH_SEPARATOR . '../lang');
+
+include("aur.inc");
+include("aurjson.class.php");
+
+$rpc_o = new AurJSON();
+if ( $_SERVER['REQUEST_METHOD'] == 'GET' ) {
+ if ( isset($_GET['type']) ) {
+ echo $rpc_o->handle($_GET);
+ }
+ else {
+ echo '<html><body>';
+ echo $rpc_o->usage();
+ echo '</body></html>';
+ }
+}
+else {
+ echo 'POST NOT SUPPORTED';
+}
+?>
diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php
new file mode 100644
index 00000000..ce59ed7d
--- /dev/null
+++ b/web/lib/aurjson.class.php
@@ -0,0 +1,145 @@
+<?php
+/**
+ * AurJSON
+ *
+ * This file contains the AurRPC remote handling class
+ * @author eliott <eliott@cactuswax.net>
+ * @version $Id$
+ * @copyright cactuswax.net, 12 October, 2007
+ * @package rpc
+ **/
+
+/**
+ * This class defines a remote interface for fetching data
+ * from the AUR using JSON formatted elements.
+ * @package rpc
+ * @subpackage classes
+ **/
+class AurJSON {
+ private $dbh = false;
+ private $exposed_methods = array('search','info');
+
+ /**
+ * Returns the usage data for the exposed json api.
+ * @return string The usage data in plain format.
+ **/
+ public function usage() {
+ $usage = 'The methods currently allowed are: <br />';
+ $usage .= '<ul>';
+ foreach ($this->exposed_methods as $methodname) {
+ $usage .= "<li>{$methodname}</li>";
+ }
+ $usage .= '</ul><br />';
+ $usage .= 'Each method requires the following HTTP GET syntax:<br />';
+ $usage .= '&nbsp;&nbsp; type=_methodname_&arg=_data_ <br /><br />';
+ $usage .= 'Where _methodname_ is the name of an exposed method, and _data_ is the data supplied as part of the call.<br />';
+ $usage .= 'The _ characters are included only in this example as placeholders. Do not use them in an actual query.<br /><br />';
+ $usage .= 'If you need jsonp type callback specification, you can provide an additional variable "callback".<br />';
+ $usage .= 'Example URL: <br />&nbsp;&nbsp; http://aur-url/rpc.php?type=search&args=foobar&callback=jsonp1192244621103';
+ return $usage;
+ }
+
+ /**
+ * Handles post data, and routes the request.
+ * @param string $post_data The post data to parse and handle.
+ * @return string The JSON formatted response data.
+ **/
+ public function handle($http_data) {
+ // set content type header to json
+ //header('content-type: application/json');
+ // set up db connection.
+ $this->dbh = db_connect();
+
+ // handle error states
+ if ( !isset($http_data['type']) || !isset($http_data['arg']) ) {
+ return $this->json_error('No request type/data specified.');
+ }
+
+ // do the routing
+ if ( in_array($http_data['type'], $this->exposed_methods) ) {
+ // ugh. this works. I hate you php.
+ $json = call_user_func_array(array(&$this,$http_data['type']),$http_data['arg']);
+ // allow rpc callback for XDomainAjax
+ if ( isset($http_data['callback']) ) {
+ return $http_data['callback'] . "({$json})";
+ }
+ else {
+ return $json;
+ }
+ }
+ else {
+ return $this->json_error('Incorrect request type specified.');
+ }
+ }
+
+ /**
+ * Returns a JSON formatted error string.
+ *
+ * @param $msg The error string to return
+ * @return mixed A json formatted error response.
+ **/
+ private function json_error($msg){
+ return $this->json_results('error',$msg);
+ }
+
+ /**
+ * Returns a JSON formatted result data.
+ * @param $type The response method type.
+ * @param $data The result data to return
+ * @return mixed A json formatted result response.
+ **/
+ private function json_results($type,$data){
+ return json_encode( array('type' => $type, 'results' => $data) );
+ }
+
+ /**
+ * Performs a fulltext mysql search of the package database.
+ * @param $keyword_string A string of keywords to search with.
+ * @return mixed Returns an array of package matches.
+ **/
+ private function search($keyword_string) {
+ $query = sprintf(
+ "SELECT Name,ID FROM Packages WHERE MATCH(Name,Description) AGAINST('%s' IN BOOLEAN MODE)",
+ mysql_real_escape_string($keyword_string, $this->dbh) );
+
+ $result = db_query($query, $this->dbh);
+
+ if ( $result && (mysql_num_rows($result) > 0) ) {
+ $search_data = array();
+ while ( $row = mysql_fetch_assoc($result) ) {
+ $elem = array(
+ 'Name' => $row['Name'],
+ 'ID' => $row['ID'] );
+ array_push($search_data,$elem);
+ }
+ mysql_free_result($result);
+ return $this->json_results('search',$search_data);
+ }
+ else {
+ return $this->json_error('No results found');
+ }
+ }
+
+ /**
+ * Returns the info on a specific package id.
+ * @param $package_id The ID of the package to fetch info.
+ * @return mixed Returns an array of value data containing the package data
+ **/
+ private function info($package_id) {
+ // using sprintf to coerce the package_id to an int
+ // should handle sql injection issues, since sprintf will
+ // bork if not an int, or convert the string to a number
+ $query = sprintf("SELECT ID,Name,Version,Description,URL,URLPath,License,NumVotes,OutOfDate,Safe FROM Packages WHERE ID=%d",$package_id);
+ $result = db_query($query, $this->dbh);
+
+ if ( $result && (mysql_num_rows($result) > 0) ) {
+ $row = mysql_fetch_assoc($result);
+ mysql_free_result($result);
+ return $this->json_results('info',$row);
+ }
+ else {
+ return $this->json_error('No result found');
+ }
+ }
+}
+?>