[xiph-commits] r14697 - in branches/dir.xiph.org: . cgi-bin cronjobs inc

balbinus at svn.xiph.org balbinus at svn.xiph.org
Thu Apr 10 13:16:42 PDT 2008


Author: balbinus
Date: 2008-04-10 13:16:41 -0700 (Thu, 10 Apr 2008)
New Revision: 14697

Added:
   branches/dir.xiph.org/inc/lib.apilog.php
   branches/dir.xiph.org/inc/lib.errors.php
Modified:
   branches/dir.xiph.org/cgi-bin/yp.php
   branches/dir.xiph.org/cronjobs/generate_tagcloud.php
   branches/dir.xiph.org/cronjobs/update_stats.php
   branches/dir.xiph.org/inc/class.mountpoint.php
   branches/dir.xiph.org/inc/class.server.php
   branches/dir.xiph.org/inc/lib.dir.php
   branches/dir.xiph.org/inc/lib.utils.php
   branches/dir.xiph.org/inc/prepend.php
   branches/dir.xiph.org/index.php
Log:
Modifications batch:

Logging in the API. Still todo: full switch to objects in the API + cronjobs.
Error logging.

 * cronjobs/generate_tagcloud.php:
     Change saving to genfile.
 * cronjobs/update_stats.php:
     We're counting servers, not mountpoints (as in yp.php).
 * cgi-bin/yp.php:
     Constants for request types, and request results. Removed the old logging
     via tempfiles. Generalized the use of exceptions, plus added logging
     through APILog. We now give the reason why the add was refused. Refuse the
     add is hostname == local IP or local host (anything not like aarggtr.ere).
 * inc/prepend.php:
     More exceptions, more includes. Plus check for SERVER_NAME in $_SERVER
     (doesn't exist in CLI).
 * inc/lib.utils.php:
     English.
 * inc/class.server.php:
     $table_name is static (and it's used in static functions ;). Added
     retrieveBySID(). Acknoledge that loadFromDb may fail.
 * inc/class.mountpoint.php:
     More or less pretty-printing.
 * inc/lib.apilog.php:
     Library for logging stuff about the API. New table api_log.
 * inc/lib.errors.php:
     Library for handling errors and exceptions.
 * inc/lib.dir.php:
     Added application/mp3 to the list of possible (but weird) MP3 mime types.
 * index.php:
     Assign by reference where possible. Load tag cloud as a genfile.


Modified: branches/dir.xiph.org/cgi-bin/yp.php
===================================================================
--- branches/dir.xiph.org/cgi-bin/yp.php	2008-04-10 18:49:44 UTC (rev 14696)
+++ branches/dir.xiph.org/cgi-bin/yp.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -2,6 +2,14 @@
 
 include_once(dirname(__FILE__).'/../inc/prepend.php');
 
+define('REQUEST_ADD', 'add');
+define('REQUEST_TOUCH', 'touch');
+define('REQUEST_REMOVE', 'remove');
+
+define('REQUEST_OK', 1);
+define('REQUEST_FAILED', 0);
+define('REQUEST_REFUSED', -1);
+
 // Do we have enough data?
 if (!array_key_exists('action', $_REQUEST))
 {
@@ -9,388 +17,398 @@
 	exit();
 }
 
-// Log the request
-/*/
-if (defined('DEBUG'))
-{
-	$fp = fopen('/tmp/dxo_'.md5(microtime()).'.test', 'w');
-	ob_start();
-	printf("======================================\n%s\n",
-		   date('Y-m-d H:i:s'));
-	print_r($_REQUEST);
-	$data = ob_get_contents();
-	ob_end_clean();
-	fwrite($fp, $data);
-}
-//*/
-$debug_data = print_r($_REQUEST, true);
-//*/
-
-try
-{
 // Memcache connection
 $memcache = DirXiphOrgMCC::getInstance();
 
 // Then process it
 switch ($_REQUEST['action'])
 {
-	case 'add':
-		// TODO: handle case where the index isn't defined.
+	case REQUEST_ADD:
 		// TODO: check that the data we get is consistent with the previous cluster data.
-		
-		// Check the args are here
-		$mandatory_args = array('sn', 'type', 'genre', 'b', 'listenurl');
-		foreach ($mandatory_args as $a)
+		try
 		{
-		    if (!array_key_exists($a, $_REQUEST))
+		    // Check the args are here
+		    $mandatory_args = array('sn', 'type', 'genre', 'b', 'listenurl');
+		    foreach ($mandatory_args as $a)
 		    {
-			    // Return failure
-			    header("YPResponse: 0");
-			    header("YPMessage: Not enough arguments.");
-			    header("SID: -1");
-/*/
-				if (defined('DEBUG'))
-			    	fwrite($fp, "\YPResponse: 0\nYPMessage: Not enough arguments.\nSID: -1");
-//*/
-				$debug_data .= "\YPResponse: 0\nYPMessage: Not enough arguments.\nSID: -1";
-//*/
+		        if (!array_key_exists($a, $_REQUEST))
+		        {
+			        throw new ServerRefusedAPIException('Not enough arguments.');
+		        }
 		    }
-		}
-		// Remote IP
-		$ip = $_SERVER['REMOTE_ADDR'];
-		// Stream name
-		$stream_name = $_REQUEST['sn'];
-		// Media type
-		$media_type = $_REQUEST['type'];
-		if (array_key_exists('stype', $_REQUEST))
-		{
-			if (preg_match('/vorbis/i', $_REQUEST['stype']))
-			{
-				$media_type .= '+vorbis';
-			}
-			if (preg_match('/theora/i', $_REQUEST['stype']))
-			{
-				$media_type .= '+theora';
-			}
-		}
-		// Genre, space-normalized
-		$genre = $_REQUEST['genre'];
-		$genre = str_replace(array('+', '-', '*', '<', '>', '~', '"', '(', ')', '|', '!', '?', ',', ';', ':'),
-							 array('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''),
-							 $genre);
-		$genre = preg_replace('/\s+/', ' ', $genre);
-		$genre_list = array_slice(explode(' ', $genre), 0, 10);
-		// Bitrate
-		$bitrate = $_REQUEST['b'];
-		// Listen URL
-		$listen_url = $_REQUEST['listenurl'];
+		    // Remote IP
+		    $ip = array_key_exists('REMOTE_ADDR', $_SERVER)
+		            ? $_SERVER['REMOTE_ADDR'] : null;
+		    // Stream name
+		    $stream_name = mb_convert_encoding($_REQUEST['sn'], 'UTF-8',
+                                               'UTF-8,ISO-8859-1,auto');
+		    // Media type
+		    $media_type = $_REQUEST['type'];
+		    if (array_key_exists('stype', $_REQUEST))
+		    {
+			    if (preg_match('/vorbis/i', $_REQUEST['stype']))
+			    {
+				    $media_type .= '+vorbis';
+			    }
+			    if (preg_match('/theora/i', $_REQUEST['stype']))
+			    {
+				    $media_type .= '+theora';
+			    }
+		    }
+		    // Genre, space-normalized
+		    $genre = mb_convert_encoding($_REQUEST['genre'], 'UTF-8',
+                                         'UTF-8,ISO-8859-1,auto');
+		    $genre = str_replace(array('+', '-', '*', '<', '>', '~', '"', '(', ')', '|', '!', '?', ',', ';', ':'),
+							     array('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''),
+							     $genre);
+		    $genre = preg_replace('/\s+/', ' ', $genre);
+		    $genre_list = array_slice(explode(' ', $genre), 0, 10);
+		    // Bitrate
+		    $bitrate = $_REQUEST['b'];
+		    // Listen URL
+		    $listen_url = $_REQUEST['listenurl'];
+            // Verify the URL
+            $url = @parse_url($listen_url);
+            if (!$url)
+            {
+                throw new ServerRefusedAPIException('Could not parse listen_url.');
+            }
+            if (empty($url['scheme']) || $url['scheme'] != 'http'
+                || !array_key_exists('host', $url)
+                || !preg_match('/^.*[A-Za-z0-9\-]+\.[A-Za-z0-9]+$/', $url['host'])
+                || preg_match('/^(10\.|192\.168\.|127\.)/', $url['host']))
+            {
+                throw new ServerRefusedAPIException('Illegal listen_url.');
+            }
 		
-		// Cluster password
-		$cluster_password = array_key_exists('cpswd', $_REQUEST) ? $_REQUEST['cpswd'] : null;
-		// Description
-		$description = array_key_exists('desc', $_REQUEST) ? $_REQUEST['desc'] : null;
-		// URL
-		$url = array_key_exists('url', $_REQUEST) ? $_REQUEST['url'] : null;
+		    // Cluster password
+		    $cluster_password = array_key_exists('cpswd', $_REQUEST) ? $_REQUEST['cpswd'] : null;
+		    // Description
+		    $description = array_key_exists('desc', $_REQUEST) ? $_REQUEST['desc'] : null;
+		    // URL
+		    $url = array_key_exists('url', $_REQUEST) ? $_REQUEST['url'] : null;
 		
-		// MySQL Connection
-		$db = DirXiphOrgDBC::getInstance();
+		    // MySQL Connection
+		    $db = DirXiphOrgDBC::getInstance();
 		
-		// Look for the mountpoint (same listen URL)
-		$server_id = $sid = null;
-		$query = 'SELECT `id`, `mountpoint_id` FROM `server` WHERE `listen_url` = "%s";';
-		$query = sprintf($query, mysql_real_escape_string($listen_url));
-		$mp_id = $server_id = false; // MySQL auto-increment keys can't be 0
-		$mp = $server = null;
-		try
-		{
-			// The mountpoint exists yet. Either an error from the Icecast server, or
-			// we didn't wipe out old stuff fast enough.
-			$res = $db->singleQuery($query);
-			$mp_id = $res->current('mountpoint_id');
-			$mp = Mountpoint::retrieveByPk($mp_id);
-			$server_id = $res->current('id');
-			$server = Server::retrieveByPk($server_id);
-		}
-		catch (SQLNoResultException $e)
-		{
-			// The mountpoint doesn't exist yet in our database (it's OK)
-		}
+		    // Look for the mountpoint (same listen URL)
+		    $server_id = $sid = null;
+		    $query = 'SELECT `id`, `mountpoint_id` FROM `server` WHERE `listen_url` = "%s";';
+		    $query = sprintf($query, mysql_real_escape_string($listen_url));
+		    $mp_id = $server_id = false; // MySQL auto-increment keys can't be 0
+		    $mp = $server = null;
+		    try
+		    {
+			    // The mountpoint exists yet. Either an error from the Icecast server, or
+			    // we didn't wipe out old stuff fast enough.
+			    $res = $db->singleQuery($query);
+			    $mp_id = $res->current('mountpoint_id');
+			    $mp = Mountpoint::retrieveByPk($mp_id);
+			    $server_id = $res->current('id');
+			    $server = Server::retrieveByPk($server_id);
+		    }
+		    catch (SQLNoResultException $e)
+		    {
+			    // The mountpoint doesn't exist yet in our database (it's OK)
+		    }
+	        
+		    // Look for the mountpoint, bis (different listen URL, same stream name)
+		    $query = 'SELECT `id` FROM `mountpoint` WHERE `stream_name` = "%s" AND `media_type_id` = %d AND `bitrate` = %d;';
+		    $query = sprintf($query, mysql_real_escape_string($stream_name), content_type_lookup($media_type), mysql_real_escape_string($bitrate));
+		    try
+		    {
+			    // The mountpoint exists, only a different server.
+			    $res = $db->singleQuery($query);
+			    $mp_id = $res->current('id');
+			    $mp = Mountpoint::retrieveByPk($mp_id);
+		    }
+		    catch (SQLNoResultException $e)
+		    {
+			    // The mountpoint doesn't exist yet in our database (it's OK)
+		    }
 		
-		// Look for the mountpoint, bis (different listen URL, same stream name)
-		$query = 'SELECT `id` FROM `mountpoint` WHERE `stream_name` = "%s" AND `media_type_id` = %d AND `bitrate` = %d;';
-		$query = sprintf($query, mysql_real_escape_string($stream_name), content_type_lookup($media_type), mysql_real_escape_string($bitrate));
-		try
-		{
-			// The mountpoint exists, only a different server.
-			$res = $db->singleQuery($query);
-			$mp_id = $res->current('id');
-			$mp = Mountpoint::retrieveByPk($mp_id);
-		}
-		catch (SQLNoResultException $e)
-		{
-			// The mountpoint doesn't exist yet in our database (it's OK)
-		}
+		    // SID
+		    $sid = UUIDGen::generate();
 		
-		// SID
-		$sid = UUIDGen::generate();
+		    // Mountpoint
+		    if (!($mp instanceOf Mountpoint))
+		    {
+		        $mp = new Mountpoint(0, false, true);
+		        $mp->setStreamName($stream_name);
+		        $mp->setDescription($description);
+		        $mp->setUrl($url);
+		        $mp->setMediaTypeId(content_type_lookup($media_type));
+		        $mp->setBitrate($bitrate);
+		        $mp->setClusterPassword($cluster_password);
+		        
+		        $mp_id = $mp->save();
+			
+			    if ($mp_id !== false)
+			    {
+			        // Log
+			        APILog::mountpointAdded(true, $mp_id, $listen_url);
+			        
+				    // Add the tags
+				    Tag::massTagMountpoint($mp, $genre_list);
+			    }
+			    else
+			    {
+			        $mp = false;
+			        
+			        // Log
+			        APILog::mountpointAdded(false, $mp_id, $listen_url);
+			    }
+		    }
 		
-		// Mountpoint
-		if (!($mp instanceOf Mountpoint))
-		{
-		    $mp = new Mountpoint(0, false, true);
-		    $mp->setStreamName($stream_name);
-		    $mp->setDescription($description);
-		    $mp->setUrl($url);
-		    $mp->setMediaTypeId(content_type_lookup($media_type));
-		    $mp->setBitrate($bitrate);
-		    $mp->setClusterPassword($cluster_password);
-		    
-		    $mp_id = $mp->save();
+		    // Server
+		    if ($mp instanceOf Mountpoint && !$server_id)
+		    {
+		        $server = new Server(0, false, true);
+		        $server->setMountpointId($mp_id);
+		        $server->setSid($sid);
+		        $server->setListenUrl($listen_url);
+		        $server->setLastTouchedFrom($ip);
+		        
+		        $server_id = $server->save();
+		        
+		        if ($server_id !== false)
+		        {
+        		    // Log
+        		    APILog::serverAdded(true, $server_id, $mp_id, $listen_url);
+		        }
+		        else
+		        {
+		            $server = false;
+		            
+        		    // Log
+        		    APILog::serverAdded(false, $server_id, $mp_id, $listen_url);
+		        }
+		    }
+	        
+		    // Tags and stuff
+		    if ($mp instanceOf Mountpoint && $server instanceOf Server)
+		    {
+			    // Increment the "total servers" key in memcache
+			    if (!$memcache->increment(ENVIRONMENT.'_servers_total'))
+     			{
+				    $memcache->set(ENVIRONMENT.'_servers_total', 1);
+			    }
+			    $ct_id = content_type_lookup($media_type);
+			    $ct_key = ENVIRONMENT.'_servers_'.intval($ct_id);
+			    if (!$memcache->increment($ct_key))
+			    {
+				    $memcache->set($ct_key, 1);
+			    }
 			
-			if ($mp instanceOf Mountpoint)
-			{
-				// Add the tags
-				Tag::massTagMountpoint($mp, $genre_list);
-			}
-		}
-/*/
-		if (defined('DEBUG'))
-			fwrite($fp, "Affected mountpoint ID: ".$mp_id."\n");
-//*/
-		$debug_data .= "Affected mountpoint ID: ".$mp_id."\n";
-//*/
-		
-		// Server
-		if ($mp instanceOf Mountpoint && !$server_id)
-		{
-		    $server = new Server(0, false, true);
-		    $server->setMountpointId($mp_id);
-		    $server->setSid($sid);
-		    $server->setListenUrl($listen_url);
-		    $server->setLastTouchedFrom($ip);
+			    // Return success
+			    header("YPResponse: 1");
+			    header("YPMessage: Successfully added.");
+			    header("SID: ".$sid);
+			    header("TouchFreq: 250");
+                
+                // Log stuff
+                APILog::request(REQUEST_ADD, true, $listen_url, $server_id,
+                                $mp_id);
+		    }
+		    else
+		    {
+			    // Return failure
+			    header("YPResponse: 0");
+			    header("YPMessage: Error occured while processing your request.");
+			    header("SID: -1");
+                
+                // Log stuff
+                APILog::request(REQUEST_ADD, false, $listen_url,
+                                $server_id !== false ? $server_id : null,
+                                $mp_id !== false ? $mp : null);
+		    }
+	    }
+	    catch (ServerRefusedAPIException $e)
+	    {
+		    // Return failure
+		    header("YPResponse: 0");
+		    header("YPMessage: Add refused. Reason: ".$e->getMessage());
+		    header("SID: -1");
 		    
-		    $server_id = $server->save();
-		}
-/*/
-		if (defined('DEBUG'))
-			fwrite($fp, "Affected server ID: ".$server_id."\n");
-//*/
-		$debug_data .= "Affected server ID: ".$server_id."\n";
-//*/
+            // Log stuff
+            APILog::request(REQUEST_ADD, REQUEST_REFUSED, $listen_url,
+                            $server_id !== false ? $server_id : null,
+                            $mp_id !== false ? $mp_id : null);
+	    }
 		
-		// Tags and stuff
-		if ($mp instanceOf Mountpoint && $server instanceOf Server)
-		{
-			// Increment the "total servers" key in memcache
-			if (!$memcache->increment(ENVIRONMENT.'_servers_total'))
- 			{
-				$memcache->set(ENVIRONMENT.'_servers_total', 1);
-			}
-			$ct_id = content_type_lookup($media_type);
-			$ct_key = ENVIRONMENT.'_servers_'.intval($ct_id);
-			if (!$memcache->increment($ct_key))
-			{
-				$memcache->set($ct_key, 1);
-			}
-			
-			// Return success
-			header("YPResponse: 1");
-			header("YPMessage: Successfully added.");
-			header("SID: ".$sid);
-			header("TouchFreq: 250");
-/*/
-			if (defined('DEBUG'))
-				fwrite($fp, "YPResponse: 1\nYPMessage: Successfully added.\nSID: ".$sid."\nTouchFreq: 250");
-//*/
-			$debug_data .=  "YPResponse: 1\nYPMessage: Successfully added.\nSID: ".$sid."\nTouchFreq: 250";
-//*/
-		}
-		else
-		{
-			// Return failure
-			header("YPResponse: 0");
-			header("YPMessage: Error occured while processing your request.");
-			header("SID: -1");
-/*/
-			if (defined('DEBUG'))
-				fwrite($fp, "\YPResponse: 0\nYPMessage: Error occured while processing your request.\nSID: -1");
-//*/
-			$debug_data .= "\YPResponse: 0\nYPMessage: Error occured while processing your request.\nSID: -1";
-//*/
-		}
-		
 		break;
-	case 'touch':
-		// TODO: handle the case where the index isn't defined.
-		// SID
-		$sid = $_REQUEST['sid'];
-		// Remote IP
-		$ip = $_SERVER['REMOTE_ADDR'];
-		// Song title
-		$current_song = mb_convert_encoding($_REQUEST['st'], 'UTF-8', 'UTF-8,ISO-8859-1,auto');
-		// Listeners
-		$listeners = $_REQUEST['listeners'];
-		// Max listeners
-		$max_listeners = $_REQUEST['max_listeners'];
+	case REQUEST_TOUCH:
+	    try
+	    {
+		    // Check the args are here
+		    $mandatory_args = array('sid');
+		    foreach ($mandatory_args as $a)
+		    {
+		        if (!array_key_exists($a, $_REQUEST))
+		        {
+			        // Return failure
+			        header("YPResponse: 0");
+			        header("YPMessage: Not enough arguments.");
+			        header("SID: -1");
+			        
+			        throw new APIException("Not enough arguments.");
+		        }
+		    }
 		
-		// MySQL Connection
-		$db = DirXiphOrgDBC::getInstance();
+		    // SID
+		    $sid = preg_replace('/[^A-F0-9\-]/', '', strtoupper ($_REQUEST['sid']));
+		    // Remote IP
+		    $ip = array_key_exists('REMOTE_ADDR', $_SERVER)
+		            ? $_SERVER['REMOTE_ADDR'] : null;
+		    // Song title
+		    $current_song = array_key_exists('st', $_REQUEST)
+		                    ? mb_convert_encoding($_REQUEST['st'], 'UTF-8',
+                                                  'UTF-8,ISO-8859-1,auto')
+                            : null;
+		    // Listeners
+		    $listeners = array_key_exists('listeners', $_REQUEST)
+		                 ? intval($_REQUEST['listeners']) : 0;
+		    // Max listeners
+		    $max_listeners = array_key_exists('max_listeners', $_REQUEST)
+        		             ? intval($_REQUEST['max_listeners']) : 0;
 		
-		// Update the data
-		$query = 'UPDATE `server` SET `current_song` = "%s", `listeners` = %d, `last_touched_from` = INET_ATON("%s"), `last_touched_at` = NOW() WHERE `sid` = "%s";';
-		$query = sprintf($query, mysql_real_escape_string($current_song), $listeners, mysql_real_escape_string($ip), mysql_real_escape_string($sid));
-/*/
-		if (defined('DEBUG'))
-		    fwrite($fp, $query."\n");
-//*/
-		$debug_data .= $query."\n";
-//*/
-		$res = $db->noReturnQuery($query);
-		if ($res && $db->affected_rows > 0)
-		{
-			// Return success
-			header("YPResponse: 1");
-			header("YPMessage: Updated server info.");
-/*/
-			if (defined('DEBUG'))
-				fwrite($fp, "\nYPResponse: 1\nYPMessage: Updated server info.");
-//*/
-			$debug_data .= "\nYPResponse: 1\nYPMessage: Updated server info.";
-//*/
+		    // MySQL Connection
+		    $db = DirXiphOrgDBC::getInstance();
+		
+		    // Update the data
+		    $server = Server::retrieveBySID($sid);
+		    if (!($server instanceOf Server))
+		    {
+		        throw new NoSuchSIDAPIException();
+		    }
+		    $query = 'UPDATE `server` SET `current_song` = "%s", `listeners` = %d, `last_touched_from` = INET_ATON("%s"), `last_touched_at` = NOW() WHERE `sid` = "%s";';
+		    $query = sprintf($query, mysql_real_escape_string($current_song), $listeners, mysql_real_escape_string($ip), mysql_real_escape_string($sid));
+		    $res = $db->noReturnQuery($query);
+		    if ($res && $db->affected_rows > 0)
+		    {
+			    // Return success
+			    header("YPResponse: 1");
+			    header("YPMessage: Updated server info.");
+			    
+                // Log stuff
+                APILog::request(REQUEST_TOUCH, true, $server->getListenUrl(),
+                                $server->getId(), $server->getMountpointId());
+		    }
+		    else
+		    {
+		        throw new NoSuchSIDAPIException();
+		    }
 		}
-		else
+		catch (NoSuchSIDAPIException $e)
 		{
-			// Return failure
-			header("YPResponse: 0");
-			header("YPMessage: SID does not exist.");
-/*/
-			if (defined('DEBUG'))
-				fwrite($fp, "\nYPResponse: 0\nYPMessage: SID does not exist.\n");
-//*/
-			$debug_data .= "\nYPResponse: 0\nYPMessage: SID does not exist.\n";
-//*/
+		    // Return failure
+		    header("YPResponse: 0");
+		    header("YPMessage: SID does not exist.");
+		    
+            // Log stuff
+            APILog::request(REQUEST_TOUCH, false, null, null, null);
 		}
+	    catch (APIException $e)
+	    {
+		    // Return failure
+		    header("YPResponse: 0");
+		    header("YPMessage: Touch impossible. Reason: ".$e->getMessage());
+		    header("SID: -1");
+		    
+            // Log stuff
+            APILog::request(REQUEST_TOUCH, false, $listen_url,
+                            $server_id !== false ? $server_id : null,
+                            $mp_id !== false ? $mp_id : null);
+	    }
 		
 		break;
-	case 'remove':
-		// SID
-		$sid = $_REQUEST['sid'];
+	case REQUEST_REMOVE:
+	    try
+	    {
+		    // Check the args are here
+		    $mandatory_args = array('sid');
+		    foreach ($mandatory_args as $a)
+		    {
+		        if (!array_key_exists($a, $_REQUEST))
+		        {
+			        // Return failure
+			        header("YPResponse: 0");
+			        header("YPMessage: Not enough arguments.");
+			        header("SID: -1");
+			        
+			        throw new APIException("Not enough arguments.");
+		        }
+		    }
 		
-		// MySQL Connection
-		$db = DirXiphOrgDBC::getInstance();
+		    // SID
+		    $sid = preg_replace('/[^a-f0-9\-]/', '', strtolower($_REQUEST['sid']));
 		
-		// Remove the data
-		$query = 'SELECT s.`id`, s.`mountpoint_id`, m.`media_type_id` FROM `server` AS s INNER JOIN `mountpoint` AS m ON s.`mountpoint_id` = m.`id` WHERE s.`sid` = "%s";';
-		$query = sprintf($query, mysql_real_escape_string($sid));
-		try
-		{
-			$res = $db->selectQuery($query);
-			$server_id = $res->current('id');
-			$mp_id = $res->current('mountpoint_id');
-			$media_type = $res->current('media_type_id');
+		    // MySQL Connection
+		    $db = DirXiphOrgDBC::getInstance();
+		
+		    // Remove the data
+		    $server = Server::retrieveBySID($sid);
+		    if (!($server instanceOf Server))
+		    {
+		        throw new NoSuchSIDAPIException();
+		    }
+		    $query = 'SELECT s.`id`, s.`mountpoint_id`, m.`media_type_id` FROM `server` AS s INNER JOIN `mountpoint` AS m ON s.`mountpoint_id` = m.`id` WHERE s.`sid` = "%s";';
+		    $query = sprintf($query, mysql_real_escape_string($sid));
+		    try
+		    {
+			    $res = $db->selectQuery($query);
+			    $server_id = $res->current('id');
+			    $mp_id = $res->current('mountpoint_id');
+			    $media_type = $res->current('media_type_id');
 			
-			// Remove server
-			$query = 'DELETE FROM `server` WHERE `id` = %d;';
-			$query = sprintf($query, $server_id);
-			$res = $db->singleQuery($query);
+			    // Remove server
+			    $query = 'DELETE FROM `server` WHERE `id` = %d;';
+			    $query = sprintf($query, $server_id);
+			    $res = $db->singleQuery($query);
 			
-			if ($res)
-			{
-				// Decrement the servers keys in memcache
-				$memcache->decrement(ENVIRONMENT.'_servers_total');
-				$memcache->decrement(ENVIRONMENT.'_servers_'.intval($media_type));
+			    if ($res)
+			    {
+				    // Decrement the servers keys in memcache
+				    $memcache->decrement(ENVIRONMENT.'_servers_total');
+				    $memcache->decrement(ENVIRONMENT.'_servers_'.intval($media_type));
 				
-				// Decrement the tag cloud values
-/*				$query = 'UPDATE `tag_cloud` SET `tag_usage` = `tag_usage` - 1 WHERE `tag_name` IN (SELECT `tag_id` FROM `mountpoints_tags` WHERE `mountpoint_id` = %d);';
-				$query = sprintf($query, $mp_id);
-				$db->noReturnQuery($query);*/
-				
-				// Return success
-				header("YPResponse: 1");
-				header("YPMessage: Deleted server info.");
-/*/
-				if (defined('DEBUG'))
-					fwrite($fp, "\nYPResponse: 1\nYPMessage: Deleted server info.");
-//*/
-				$debug_data .= "\nYPResponse: 1\nYPMessage: Deleted server info.";
-//*/
-			}
-			else
-			{
-				// Return failure
-				header("YPResponse: 0");
-				header("YPMessage: Error occured while processing your request.");
-/*/
-				if (defined('DEBUG'))
-					fwrite($fp, "\YPResponse: 0\nYPMessage: Error occured while processing your request.");
-//*/
-				$debug_data .= "\YPResponse: 0\nYPMessage: Error occured while processing your request.";
-//*/
-			}
-			
-/*			if ($cluster_id != null)
-			{
-				// See if cluster is empty
-				$query = 'SELECT 1 FROM `mountpoints` WHERE `cluster_id` = %d LIMIT 1;';
-				$query = sprintf($query, $cluster_id);
-				try
-				{
-					$res = $db->singleQuery($query);
-					
-					// OK, we can leave the cluster
-				}
-				catch (SQLNoResultException $e)
-				{
-					// No other server: delete the cluster
-					$query = 'DELETE FROM `clusters` WHERE `id` = %d;';
-					$query = sprintf($query, $cluster_id);
-					$res = $db->singleQuery($query);
-				}
-			}*/
+				    // Return success
+				    header("YPResponse: 1");
+				    header("YPMessage: Deleted server info.");
+				    
+                    // Log stuff
+                    APILog::request(REQUEST_REMOVE, true, $server->getListenUrl(),
+                                    $server->getId(), $server->getMountpointId());
+			    }
+			    else
+			    {
+				    // Return failure
+				    header("YPResponse: 0");
+				    header("YPMessage: Error occured while processing your request.");
+				    
+                    // Log stuff
+                    APILog::request(REQUEST_REMOVE, false, $server->getListenUrl(),
+                                    $server->getId(), $server->getMountpointId());
+			    }
+		    }
+		    catch (SQLNoResultException $e)
+		    {
+			    throw new NoSuchSIDAPIException();
+		    }
 		}
-		catch (SQLNoResultException $e)
+		catch (NoSuchSIDAPIException $e)
 		{
-			// Return failure
-			header("YPResponse: 0");
-			header("YPMessage: SID does not exist.");
-/*/
-			if (defined('DEBUG'))
-				fwrite($fp, "\nYPResponse: 0\nYPMessage: SID does not exist.");
-//*/
-			$debug_data .= "\nYPResponse: 0\nYPMessage: SID does not exist.";
-//*/
+		    // Return failure
+		    header("YPResponse: 0");
+		    header("YPMessage: SID does not exist.");
+		
+            // Log stuff
+            APILog::request(REQUEST_REMOVE, false, $listen_url,
+                            $server_id !== false ? $server_id : null,
+                            $mountpoint_id !== false ? $mountpoint_id : null);
 		}
 		
 		break;
-	default:
-/*/
-		if (defined('DEBUG'))
-			fwrite($fp, "\nUnrecognized action '".$_REQUEST['action']."'");
-//*/
-		$debug_data .= "\nUnrecognized action '".$_REQUEST['action']."'";
-//*/
 }
-}
-catch (SQLException $e)
-{
-/*/
-	if (defined('DEBUG'))
-		fwrite($fp, "\nMySQL Error: ".$e->getMessage());
-//*/
-	$debug_data .= "\nMySQL Error: ".$e->getMessage();
-//*/		
-}
 
-/*/
-if (defined('DEBUG'))
-{
-	fwrite($fp, "\n");
-	fclose($fp);
-}
-//*/
-$sql = 'INSERT INTO `yp_log` (`log_data`) VALUES ("%s");';
-$sql = sprintf($sql, mysql_real_escape_string($debug_data));
-$db->noReturnQuery($sql);
-//*/
-
 ?>

Modified: branches/dir.xiph.org/cronjobs/generate_tagcloud.php
===================================================================
--- branches/dir.xiph.org/cronjobs/generate_tagcloud.php	2008-04-10 18:49:44 UTC (rev 14696)
+++ branches/dir.xiph.org/cronjobs/generate_tagcloud.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -45,9 +45,9 @@
 	return $s;
 }
 $res = array_map('add_popularity', $res);
-var_dump($res);
-// Save into memcache
-$memcache->set(ENVIRONMENT.'_tagcloud', $res, 0, 600); // 10 mins
+
+// Save into a genfile
+genfile::write(genfile::makeGenfileName('tagcloud'), $res) or die("Unable to save data in a genfile.\n");
 echo "OK.\n";
 
 ?>

Modified: branches/dir.xiph.org/cronjobs/update_stats.php
===================================================================
--- branches/dir.xiph.org/cronjobs/update_stats.php	2008-04-10 18:49:44 UTC (rev 14696)
+++ branches/dir.xiph.org/cronjobs/update_stats.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -10,8 +10,8 @@
 $memcache = DirXiphOrgMCC::getInstance();
 
 // Base query
-$query_pattern = 'SELECT COUNT(id) AS `count` FROM `mountpoint` WHERE %s;';
-$where_pattern = '`media_type_id` = "%s"';
+$query_pattern = 'SELECT COUNT(*) AS `count` FROM `server` AS s INNER JOIN `mountpoint` AS m ON m.`id` = s.`mountpoint_id` WHERE %s;';
+$where_pattern = 'm.`media_type_id` = "%s"';
 
 // MP3
 $where = sprintf($where_pattern, CONTENT_TYPE_MP3);

Modified: branches/dir.xiph.org/inc/class.mountpoint.php
===================================================================
--- branches/dir.xiph.org/inc/class.mountpoint.php	2008-04-10 18:49:44 UTC (rev 14696)
+++ branches/dir.xiph.org/inc/class.mountpoint.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -114,25 +114,20 @@
 		$db = DirXiphOrgDBC::getInstance();
 		
 		// Query
-        $query = "SELECT * FROM `%s` WHERE `id` = %d;";
-        $query = sprintf($query, $this->table_name, $this->mountpoint_id);
         try
         {
+            $query = "SELECT * FROM `%s` WHERE `id` = %d;";
+            $query = sprintf($query, $this->table_name, $this->mountpoint_id);
             $m = $db->singleQuery($query);
+            
+            $this->loadFromArray($m->array_data[0]);
+            
+            return true;
         }
         catch (SQLNoResultException $e)
         {
             return false;
         }
-        
-        if (!$m)
-        {
-            return false;
-        }
-        
-        $this->loadFromArray($m->array_data[0]);
-        
-        return true;
     }
     
     /**

Modified: branches/dir.xiph.org/inc/class.server.php
===================================================================
--- branches/dir.xiph.org/inc/class.server.php	2008-04-10 18:49:44 UTC (rev 14696)
+++ branches/dir.xiph.org/inc/class.server.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -3,7 +3,7 @@
 class Server
 {
     protected $server_id;
-    protected $table_name = 'server';
+    protected static $table_name = 'server';
     protected $cache_expiration = 60;
     public $loaded = false;
     
@@ -65,6 +65,30 @@
     }
     
     /**
+     * Retrieves the server from the db.
+     * 
+     * @return Server or false if an error occured.
+     */
+    public static function retrieveBySID($sid)
+    {
+        // MySQL Connection
+		$db = DirXiphOrgDBC::getInstance();
+		
+		try
+		{
+		    $sql = "SELECT `id` FROM %s WHERE `sid` = '%s';";
+		    $sql = sprintf($sql, self::$table_name, mysql_real_escape_string($sid));
+		    $res = $db->singleQuery($sql);
+	    }
+	    catch (SQLNoResultException $e)
+		{
+		    return false;
+		}
+		
+		return self::retrieveByPk(intval($res->current('id')));
+    }
+    
+    /**
      * Saves the server into the database.
      * 
      * @return integer
@@ -78,7 +102,7 @@
         $query = 'INSERT INTO `%1$s` (`mountpoint_id`, `sid`, `current_song`, `listen_url`, `listeners`, `last_touched_at`, `last_touched_from`) '
 			    .'VALUES (%2$d, "%3$s", %4$s, "%5$s", %6$d, %7$s, INET_ATON("%8$s")) '
 			    .'ON DUPLICATE KEY UPDATE `mountpoint_id` = %2$d, `sid` = "%3$s", `current_song` = %4$s, `listen_url` = "%5$s", `listeners` = %6$d, `last_touched_at` = %7$s, `last_touched_from` = INET_ATON("%8$s");';
-	    $query = sprintf($query, $this->table_name,
+	    $query = sprintf($query, self::$table_name,
 	                             $this->mountpoint_id,
 							     mysql_real_escape_string($this->sid),
 							     ($this->current_song != null) ? '"'.mysql_real_escape_string($this->current_song).'"' : 'NULL',
@@ -102,18 +126,20 @@
 		$db = DirXiphOrgDBC::getInstance();
 		
 		// Query
-        $query = "SELECT `mountpoint_id`, `sid`, `current_song`, `listen_url`, `listeners`, `last_touched_at`, INET_NTOA(`last_touched_from`) AS `last_touched_from` FROM `%s` WHERE `id` = %d;";
-        $query = sprintf($query, $this->table_name, $this->server_id);
-        $m = $db->singleQuery($query);
-        
-        if (!$m)
+		try
+		{
+            $query = "SELECT `mountpoint_id`, `sid`, `current_song`, `listen_url`, `listeners`, `last_touched_at`, INET_NTOA(`last_touched_from`) AS `last_touched_from` FROM `%s` WHERE `id` = %d;";
+            $query = sprintf($query, self::$table_name, $this->server_id);
+            $m = $db->singleQuery($query);
+            
+            $this->loadFromArray($m->array_data[0]);
+            
+            return true;
+        }
+        catch (SQLNoResultException $e)
         {
             return false;
         }
-        
-        $this->loadFromArray($m->array_data);
-        
-        return true;
     }
     
     /**

Added: branches/dir.xiph.org/inc/lib.apilog.php
===================================================================
--- branches/dir.xiph.org/inc/lib.apilog.php	                        (rev 0)
+++ branches/dir.xiph.org/inc/lib.apilog.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -0,0 +1,56 @@
+<?php
+
+class APILog
+{
+    public static function log($result, $listen_url = null,
+                               $server_id = null, $mountpoint_id = null)
+    {
+        $db = DirXiphOrgDBC::getInstance();
+        $sql = 'INSERT INTO `api_log` (`message`, `remote_ip`, `listen_url_hash`, `server_id`, `mountpoint_id`) '
+              .'VALUES ("%s", INET_ATON("%s"), %u, %d, %d);';
+        $sql = sprintf($sql, mysql_real_escape_string($result),
+                             array_key_exists('REMOTE_ADDR', $_SERVER)
+                                ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',
+                             $listen_url !== null ? sprintf('%u', crc32($listen_url)) : 0,
+                             $server_id, $mountpoint_id);
+        $db->noReturnQuery($sql);
+        
+/*        mail_error('annie.dupont1137 at gmail.com', 'log-api',
+                   $result, __FILE__, 0);*/
+    }
+    
+    public static function serverAdded($ok, $server_id, $mountpoint_id,
+                                       $listen_url)
+    {
+        self::log($ok ?'Server added' : 'Server add failed',
+                  $listen_url, $server_id, $mountpoint_id);
+    }
+    
+    public static function mountpointAdded($ok, $mountpoint_id,
+                                           $listen_url = null)
+    {
+        self::log($ok ? 'Mountpoint added' : 'Mountpoint add failed',
+                  $listen_url, null, $mountpoint_id);
+    }
+    
+    public static function request($req_type, $ok, $listen_url = null,
+                                   $server_id = null, $mountpoint_id = null)
+    {
+        $message = '';
+        switch ($ok)
+        {
+            case REQUEST_OK:
+                $message = strtoupper($req_type) . ' OK';
+                break;
+            case REQUEST_FAILED:
+                $message = strtoupper($req_type) . ' failed';
+                break;
+            case REQUEST_REFUSED:
+                $message = strtoupper($req_type) . ' refused';
+                break;
+        }
+        self::log($message, $listen_url, $server_id, $mountpoint_id);
+    }
+}
+
+?>

Modified: branches/dir.xiph.org/inc/lib.dir.php
===================================================================
--- branches/dir.xiph.org/inc/lib.dir.php	2008-04-10 18:49:44 UTC (rev 14696)
+++ branches/dir.xiph.org/inc/lib.dir.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -28,7 +28,7 @@
 	}
 	
 	// MP3
-	elseif ($content_type == "audio/mpeg" || $content_type == "audio/x-mpeg")
+	elseif ($content_type == "audio/mpeg" || $content_type == "audio/x-mpeg" || $content_type == 'application/mp3')
 	{
 		return CONTENT_TYPE_MP3;
 	}

Added: branches/dir.xiph.org/inc/lib.errors.php
===================================================================
--- branches/dir.xiph.org/inc/lib.errors.php	                        (rev 0)
+++ branches/dir.xiph.org/inc/lib.errors.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -0,0 +1,99 @@
+<?php
+
+define('ERROR_RECIPIENT', 'balbinus at orbus.fr');
+define('ERROR_SENDER', 'bug');
+
+function mail_error($mail_to, $mail_from,
+                    $errstr, $errfile, $errline, $trace='')
+{
+    $data = <<<EOF
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+    <head>
+        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+        <title>Erreur</title>
+        <style type="text/css">
+
+        </style>
+    </head>
+    <body>\n
+EOF;
+    $data .= sprintf("        <h1>Error: %s</h1>
+        <h2><code>%s</code>, <code>line %d</code></h2>\n",
+                     $errstr, $errfile, $errline);
+    $data .= sprintf("        <hr />
+        <dl>
+            <dt>Date:</dt>
+            <dd>%s</dd>
+            <dt>Remote address:</dt>
+            <dd>%s</dd>
+            <dt>Path:</dt>
+            <dd><code>%s</code></dd>
+        </dl>
+        <hr />
+        <h3>Trace</h3>
+        <pre>%s</pre>
+        <hr />
+        <h3>\$_SERVER</h3>
+        <pre>%s</pre>
+        <h3>\$_REQUEST</h3>
+        <pre>%s</pre>\n",
+                     gmdate('r'),
+                     array_key_exists('REMOTE_ADDR', $_SERVER)
+                        ? $_SERVER['REMOTE_ADDR'] : '???',
+                     array_key_exists('REQUEST_PATH', $_SERVER)
+                        ? $_SERVER['REQUEST_PATH'] : '???',
+                     print_r($trace, true),
+                     print_r($_SERVER, true),
+                     print_r($_REQUEST, true));
+    $data .= <<<EOF
+    </body>
+</html>
+EOF;
+    
+    $env = defined('ENVIRONMENT') ? ' '.ENVIRONMENT : '';
+    @mail($mail_to, '[DXO'.$env.'] Error: '.$errstr, $data,
+          'From: <' . $mail_from . '>' . "\n" .
+          'Content-Type: text/html; charset=iso-8859-1' . "\n");
+}
+
+function custom_exception_handler($e)
+{
+    $msg = $e->getMessage();
+    $msg = empty($msg) ? 'Exception '.get_class($e) : $msg;
+    
+    mail_error(ERROR_RECIPIENT, ERROR_SENDER,
+               $msg, $e->getFile(), $e->getLine(), $e->getTrace());
+}
+
+function error_handler_exception_callback($errno, $errstr, $errfile='Unknown', $errline=0, $errcontext=null)
+{
+    // @-ignored error
+    if (($errno & error_reporting()) === 0)
+    {
+        return;
+    }
+
+    // NOTICE
+    if ($errno == E_NOTICE || $errno == E_USER_NOTICE)
+    {
+        return;
+    }
+
+    // STRICT
+    if ($errno == E_STRICT)
+    {
+        return;
+    }
+
+    $e = new DXOException($errstr, $errno);
+    $e->setErrorFile($errfile);
+    $e->setErrorLine($errline);
+    
+    throw $e;
+}
+
+set_exception_handler('custom_exception_handler');
+set_error_handler('error_handler_exception_callback');
+
+?>

Modified: branches/dir.xiph.org/inc/lib.utils.php
===================================================================
--- branches/dir.xiph.org/inc/lib.utils.php	2008-04-10 18:49:44 UTC (rev 14696)
+++ branches/dir.xiph.org/inc/lib.utils.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -3,9 +3,9 @@
 class utils
 {
     /**
-     * Détecte si une chaîne est en UTF8
+     * Returns true if the string is correct UTF-8
      */
-    public static function is_utf8($str)
+    public static function is_UTF8($str)
     {
         if (preg_match('%^(?:
              [\x09\x0A\x0D\x20-\x7E]            # ASCII

Modified: branches/dir.xiph.org/inc/prepend.php
===================================================================
--- branches/dir.xiph.org/inc/prepend.php	2008-04-10 18:49:44 UTC (rev 14696)
+++ branches/dir.xiph.org/inc/prepend.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -1,18 +1,37 @@
 <?php
 
-class BadIDException extends Exception { }
-class EnvironmentUndefinedException extends Exception { }
+class DXOException extends Exception
+{
+    public function setErrorLine($el)
+    {
+        $this->line = $el;
+    }
+    
+    public function setErrorFile($ef)
+    {
+        $this->file = $ef;
+    }
+}
 
+class BadIDException extends DXOException { }
+class EnvironmentUndefinedException extends DXOException { }
+
+class APIException extends DXOException { }
+class ServerRefusedAPIException extends APIException { }
+class NoSuchSIDAPIException extends APIException { }
+
 if (getenv('ENVIRONMENT') !== false)
 {
 	define('ENVIRONMENT', strtolower(getenv('ENVIRONMENT')));
 }
-elseif ($_SERVER['SERVER_NAME'] == 'directory-test.radiopytagor.net')
+elseif (array_key_exists('SERVER_NAME', $_SERVER)
+        && $_SERVER['SERVER_NAME'] == 'directory-test.radiopytagor.net')
 {
 	define('ENVIRONMENT', 'preprod');
 }
-elseif ($_SERVER['SERVER_NAME'] == 'directory.radiopytagor.net'
-		|| $_SERVER['SERVER_NAME'] == 'dir.xiph.org')
+elseif (array_key_exists('SERVER_NAME', $_SERVER)
+        && ($_SERVER['SERVER_NAME'] == 'directory.radiopytagor.net'
+       		|| $_SERVER['SERVER_NAME'] == 'dir.xiph.org'))
 {
 	define('ENVIRONMENT', 'prod');
 }
@@ -34,6 +53,8 @@
 
 $begin_time = microtime(true);
 
+include_once(dirname(__FILE__).'/lib.errors.php');
+
 // Classes
 include_once(dirname(__FILE__).'/prepend.php');
 include_once(dirname(__FILE__).'/class.db.php');
@@ -54,5 +75,6 @@
 include_once(dirname(__FILE__).'/lib.uuidgen.php');
 include_once(dirname(__FILE__).'/lib.dir.php');
 include_once(dirname(__FILE__).'/lib.utils.php');
+include_once(dirname(__FILE__).'/lib.apilog.php');
 
 ?>

Modified: branches/dir.xiph.org/index.php
===================================================================
--- branches/dir.xiph.org/index.php	2008-04-10 18:49:44 UTC (rev 14696)
+++ branches/dir.xiph.org/index.php	2008-04-10 20:16:41 UTC (rev 14697)
@@ -11,11 +11,13 @@
 // Get the data from the Memcache server
 $top = genfile::get(genfile::makeGenfileName('home_top'));
 $top = array_map(array('Mountpoint', 'retrieveByPk'), $top);
-$tpl->assign('data', $top);
+$tpl->assign_by_ref('data', $top);
+$tpl->assign('tag_cloud', genfile::get(genfile::makeGenfileName('tagcloud')));
+
+// Stats
 $tpl->assign('servers_total', $memcache->get(ENVIRONMENT.'_servers_total'));
 $tpl->assign('servers_mp3', $memcache->get(ENVIRONMENT.'_servers_'.CONTENT_TYPE_MP3));
 $tpl->assign('servers_vorbis', $memcache->get(ENVIRONMENT.'_servers_'.CONTENT_TYPE_OGG_VORBIS));
-$tpl->assign('tag_cloud', $memcache->get(ENVIRONMENT.'_tagcloud'));
 $tpl->display('index.tpl');
 
 // Footer



More information about the commits mailing list