View file radio/Classes/Statistic.class.php

File size: 12.26Kb
<?php
	class Statistic {
		const ICON_PATH = "/radio/players/";
        
        public static $object;
        
        public static function create() {
            if (self::$object === null) {
                self::$object = new self();
            }
            
            return self::$object;
        }
        
        private function __construct() {
            $this->db = MySql::create();
            $this->setting = Setting::create();
            $this->request = Request::create();
        }

		public $icons = array(
			"WinAmp" 			=> array(
									'icon' => "winamp.gif",
									'clients' => 'winamp'
								),					
			"Консоль PSP" 		=> array(
									'icon' => "psp.png",
									'clients' => 'psp'
								),
			"The Nemesis Player" => array(
									'icon' => "nsplayer.png",
									'clients' => 'nsplayer'
								),
			"Internet Explorer" => array(
									'icon' => "msie.gif",
									'clients' => 'msie'
								),
			"Радио-станция Icecast" => array(
									'icon' => "icecast.png",
									'clients' => 'icecast'
								),
			"Радио-станция Shoutcast"	=> array(
									'icon' => "shoutcast.png",
									'clients' => 'shoutcast'
								),
			"Устройства Apple"	=> array(
									'icon' => "apple.png",
									'clients' => 'ipad, iphone, ipod'
								),
			"VLC-плеер" 		=> array(
									'icon' => "vlc.jpg",
									'clients' => 'vlc'
								),
			"Foobar2000" 		=> array(
									'icon' => "foobar2000.png",
									'clients' => 'foobar2000'
								),
			"Браузер Opera" 		=> array(
									'icon' => "opera.png",
									'clients' => 'opera'
								),
		    "Браузер Chrome"       => array(
                                    'icon' => "chrome.png",
                                    'clients' => 'chrome'
                                ),
			"Windows Media Player" 	=> array(
									'icon' => "wmplayer.gif",
									'clients' => 'wmplayer, windows-media'
								),
			"JetAudio-плеер" 			=> array(
									'icon' => "jetaudio.png",
									'clients' => 'jetaudio'
								),
			"Библиотека BASS" 	=> array(
									'icon' => "bass.gif",
									'clients' => 'bass'
								),
			"Библиотека liquidsoap" 		=> array(
									'icon' => "liquidsoap.gif",
									'clients' => 'liquidsoap'
								),
			"Screamer-плеер" 	=> array(
									'icon' => "screamer.png",
									'clients' => 'screamer'
								),
			"iRusRadio" 		=> array(
									'icon' => "irusradio.gif",
									'clients' => 'irusradio'
								),
			"Устройства Android" => array(
									'icon' => "android.png",
									'clients' => 'android'
								),
			"Устройства Sony"	=> array(
									'icon' => "sonyericsson.png",
									'clients' => 'sony'
								),
			"TuneIn Radio"	=> array(
									'icon' => "tunein.png",
									'clients' => 'tunein'
								),
			"ITunes"	=> array(
									'icon' => "itunes.png",
									'clients' => 'itunes'
								),
			"FreeAMP"	=> array(
									'icon' => "freeamp.png",
									'clients' => 'freeamp'
								),
			"Real Media Player"	=> array(
									'icon' => "realmedia.png",
									'clients' => 'realmedia'
								),
			"XMMS-плеер"	=> array(
									'icon' => "xmms.png",
									'clients' => 'xmms'
								),
			"GStreamer-фреймоврк"	=> array(
									'icon' => "gstreamer.png",
									'clients' => 'gstreamer'
								),
			"Audacious Media Player"	=> array(
									'icon' => "audacious.png",
									'clients' => 'audacious'
								),
			"Проигрыватель AIMP"	=> array(
									'icon' => "aimp.png",
									'clients' => 'aimp'
								),		
			"Библиотека Libav" => array(
                                    'icon' => "libav.png",
                                    'clients' => 'lavf52'
                                ), 
            "Браузер Firefox"=> array(
                                    'icon' => "gecko.png",
                                    'clients' => 'firefox, mozilla'
                                ),                      	                   							
		);

		public function updateAll() {
  			$status = $this->requestIcecastStatus();
			$this->updateListeners();
  			$this->updateStatistic($status);
  			$this->updateClients($status);
		}
        
        public function updateMain() {
            $status = $this->requestIcecastStatus();
            $this->updateListeners();
            $this->updateStatistic($status);
        }

		public function getIcon($agent) {
        	foreach ($this->icons as $name=>$player) {
        		$clients = explode(",", $player['clients']);
        		foreach ($clients as $client) {
        			if (strpos(strtolower($agent), strtolower(trim($client)))!==false) {
        				return self::ICON_PATH.$player['icon'];
        			}
        		}
        	}
		}

		public function getClient($agent) {
        	foreach ($this->icons as $name=>$player) {
        		$clients = explode(",", $player['clients']);
        		foreach ($clients as $client) {
        			if (strpos(strtolower($agent), strtolower(trim($client)))!==false) {
        				return $name;
        			}
        		}
        	}

        	return $agent;
		}

		public function getTime($time) {
  			$hour = floor($time/3600);
    		$min = floor(($time%3600)/60);
    		$sec = ($time%3600)%60;

    		$time = "";

			if ($hour != 0) {
				$time .= "$hour ч. ";
			}
			if ($min != 0) {
				$time .= "$min мин. ";
			}
			if (($hour == 0) and ($min == 0) and ($sec != 0)) {
				$time .= "$sec сек.";
			}
			if (($hour == 0) and ($min == 0) and ($sec == 0)) {
				$time .= "1 сек.";
			}

			return $time;
		}

		public function getClients() {
			$query = "SELECT * FROM `statistic` WHERE `type` = 'graph' ORDER BY `time` DESC";
			return $this->db->getLines($query);
		}

		public function getLastSongs() {
			$query = "SELECT * FROM `tracklist` ORDER BY `time` DESC";
			return $this->db->getLines($query);
		}
		
		public function getSystemStreamArray() {
			$streams = explode(",", $this->setting->getSystemStream());
			$tochka = $this->getEzstreamPoint();
			foreach ($streams as $stream) {
				$return[trim($stream)] = trim($stream);
			}	
			$return[$tochka] = $tochka;

			return $return;
		}
		
		private function extractUrlsBySourcesAndStreams($sources, $streams) {
			if (!is_array($sources)) {
				$sources = array($sources);
			}
			
			$urls = array();
			foreach ($sources as $source) {
				foreach ($streams as $v) {
					$point = substr($source->listenurl, strrpos($source->listenurl, "/") + 1, strlen($source->listenurl));
					if (trim($point) == trim($v)) {
						if (strpos(IP, "http://") === false) {
							$addr = "http://" . IP;
						}
						$urls[] = $addr . ":" . PORT . "/admin/listclients.xsl?mount=/" . $point;
					}
				}	
			}
			
			return $urls;
		}

		public function updateClients($status) {
			$query = "SELECT * FROM  `settings` WHERE `name` = 'listeners' LIMIT 1";
			$line = $this->db->getLine($query);
 			$full_numbers = explode("||", $line['value']);
 			$streams = $this->getSystemStreamArray();
			
			$json = json_decode($line['value']);
			
			$url = array();
			if (isset($json->icestats->source)) {
				$url = $this->extractUrlsBySourcesAndStreams($json->icestats->source, $streams);
			}

			$count_mount = count($url)+1;
			$ik = 1;
			$rand = 1; //
			if ($rand == 1) {
				$date = date("U")+86400;
				$date_today = $date;
				$query = "DELETE FROM `statistic` WHERE `type` = 'graph' and `date` < $date_today";
				$this->db->queryNull($query);
				
				if (!empty($url))
				foreach ($url as $link) {
					$ch = curl_init();
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
					curl_setopt($ch, CURLOPT_URL, $link);
					curl_setopt($ch, CURLOPT_USERPWD, ICE_LOGIN.":".ICE_PASS);
					$result = curl_exec($ch);

					curl_close($ch);

					preg_match_all('/<tr.*?>(.*?)<\\/[\s]*tr>/s', $result, $matches);
					
					foreach ($matches[1] as $row) {
						preg_match_all("/<td.*?>(.*?)<\/td>/", $row, $td_matches);
						
						if (!is_numeric($td_matches[1][1])) {
							continue;
						}
						
						$cIp = addslashes($td_matches[1][0]);
						$cTimeSec = addslashes($td_matches[1][1]);
						$cClient = addslashes($td_matches[1][2]);
						$date = time();
						
						$query = "INSERT INTO `statistic` (`type` ,`ip` ,`country` ,`country_name` ,`time` ,`client` ,`date`)
					       VALUES ('graph', '" . $cIp . "', '','', '" . $cTimeSec ."', '". $cClient ."', '" . $date . "')";
						$this->db->queryNull($query);
					}
				}
			}
		}

		public function updateListeners() {
			$query = "SELECT * FROM `statistic` WHERE `type` = 'day'";
			$count = $this->db->getCountRow($query);

			$query = "DELETE FROM `statistic` WHERE (($count>122) and (`type` = 'day')) ORDER BY `time` LIMIT 2;";
			$this->db->queryNull($query);
			
			$date = date("U");
			$query = "SELECT * FROM `statistic` WHERE `type` = 'day' ORDER BY `time` DESC";
			$posl_time = $this->db->getColumn($query, 'time');
			$posl_time = $posl_time + 600;

			if ($posl_time < $date)  {
				$query="INSERT INTO `statistic` (`type` ,`listeners`, `time`) VALUES ('day', '".$this->getListeners()."', '".$date."')";
				$this->db->queryNull($query);
			}
		}	

		public function updateStatistic($jsonStatusText) {
			$full_numbers = addslashes($jsonStatusText);

			$query = "SELECT * FROM  `settings` WHERE `name`='listeners' LIMIT 1";
			$line = $this->db->getLine($query);

			if (!empty($line)) {
				$query="UPDATE `settings` SET `value` = '$full_numbers' WHERE `name`= 'listeners';";
				$this->db->queryNull($query);
			} else {
				$query="INSERT INTO `settings` ( `name` , `value` ) VALUES ('listeners', '$full_numbers');";
			 	$this->db->queryNull($query);
			}
        }

		public function getStreamCount() {

            $query="SELECT * FROM  `settings` WHERE `name`='listeners' LIMIT 1";
 			$line = $this->db->getLine($query);

			$json = json_decode($line['value']);

 			$potok = 0;
			$listeners = 0;
			if (isset($json->icestats->source)) {
				foreach ($json->icestats->source as $source) {
					$listeners += $source->listeners;
					$potok += 1;
				}
			}

			return $potok;
		}

		public function getListeners() {
            $query = "SELECT * FROM  `settings` WHERE `name`='listeners' LIMIT 1";
 			$line = $this->db->getLine($query);
			
			$json = json_decode($line['value']);

 			$potok = 0;
			$listeners = 0;
			if (isset($json->icestats->source)) {
				if (is_array($json->icestats->source)) {
					foreach ($json->icestats->source as $source) {
						$listeners += $source->listeners;
						$potok += 1;
					}
				} else {
					$listeners += $json->icestats->source->listeners;
				}
			} else {
				$listeners = 0;
			}

			return $listeners;
		}

		public function getEzstreamPoint() {
			$rf_ez = file(CF_EZSTREAM);
			if ($rf_ez) {
				for ($i=0; $i<count($rf_ez); $i++) {
					if (strpos($rf_ez[$i], '<url>')!==false) {
						$cf_ez_url = $rf_ez[$i];
					}
				}
			}
			$cf_ez_url =  str_replace("</url>", "", $cf_ez_url);
			$cf_ez_url =  str_replace("<url>", "", $cf_ez_url);
			$cf_ez_url = explode("/", $cf_ez_url);
			$cf_ez_url = $cf_ez_url[3];
    		$cf_ez_url = str_replace("\n", "", $cf_ez_url);

    		return trim($cf_ez_url);
		}

		public function requestIcecastStatus() {
        	$fp = @fsockopen(IP, PORT, $errno, $errstr, 1);
			if (empty($fp)) {
				return false;
			} else {
				fputs($fp, "GET /status-json.xsl HTTP/1.0\r\nUser-Agent: Icecast2 XSL Parser (Mozilla Compatible)\r\n\r\n");
 				$page = "";
 				while(!feof($fp)) {
  					$page .= fgets($fp, 1000);
				}
				fclose($fp);
				
				$jsonText = substr($page, strpos($page, "{"));
				
				return $jsonText;
			}
		}

		public function updateDirectory() {
			$url = "http://radiocms.ru/stations.php?name=".DIR_NAME.
				"&url=".DIR_URL.
				"&stream=".DIR_STREAM.
				"&description=".DIR_DESCRIPTION.
				"&genre=".DIR_GENRE.
				"&listeners=".$this->getListeners().
				"&bitrate=".DIR_BITRATE."&ip=".IP.
				"&charset=utf-8";

            $this->request->get($url);
		}
	}
?>