Mass move to root
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
class Config {
|
||||
|
||||
private static $_config = array();
|
||||
|
||||
public static function loadFile($config_name, $file_path) {
|
||||
self::$_config[$config_name] = parse_ini_file($file_path, true);
|
||||
}
|
||||
|
||||
public static function get($str) {
|
||||
$path = explode(':', $str);
|
||||
$res = self::$_config;
|
||||
for ($i = 0; $i < count($path); $i++) {
|
||||
$res = $res[$path[$i]];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/*****************************************************************
|
||||
Пример использования:
|
||||
|
||||
$weight_calc = new TrackWeight();
|
||||
$weight_calc->setTrackData('Blondie', 'Call Me', 210);
|
||||
$weight_calc->setFiles($files); // Файлы, полученные от парсера
|
||||
$weight_calc->calculateWeight();
|
||||
$files = $weight_calc->getFiles();
|
||||
*****************************************************************/
|
||||
|
||||
/**
|
||||
* Класс посчета веса файла (коэфициента, определяющего релевантность)
|
||||
*
|
||||
* @package classes
|
||||
* @author chez
|
||||
**/
|
||||
class TrackWeight {
|
||||
|
||||
private $_artist; // Имя исполнителя
|
||||
private $_track; // Название трека
|
||||
private $_duration; // Длительность трека в секундах
|
||||
|
||||
private $_files; // Массив файлов для сравнения
|
||||
|
||||
/**
|
||||
* Задает параметры оригинального трека
|
||||
*
|
||||
* @param string $artist Имя исполнителя
|
||||
* @param string $track Запрос
|
||||
* @param int $duration Длительность трека в секундах
|
||||
* @return void
|
||||
* @author chez
|
||||
**/
|
||||
public function setTrackData($artist, $track, $duration) {
|
||||
$this->_artist = $artist;
|
||||
$this->_track = $track;
|
||||
$this->_duration = $duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Задает массив файлов для сравнения
|
||||
*
|
||||
* @param array $files Массив файлов для сравнения
|
||||
* @return void
|
||||
* @author chez
|
||||
**/
|
||||
public function setFiles($files) {
|
||||
$this->_files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает файлы с проставленным весом
|
||||
*
|
||||
* @return array $files Массив файлов
|
||||
* @author chez
|
||||
**/
|
||||
public function getFiles() {
|
||||
return $this->_files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Рассчитывает вес для каждого файла
|
||||
*
|
||||
* @return void
|
||||
* @author chez
|
||||
**/
|
||||
public function calculateWeight() {
|
||||
foreach ($this->_files as $i => $file) {
|
||||
$weight = 0;
|
||||
|
||||
if ($file['artist'] == $this->_artist) {
|
||||
$weight += 10;
|
||||
} elseif (strpos($file['artist'], $this->_artist) !== false) {
|
||||
$weight += 5;
|
||||
} elseif (strpos($file['track'], $this->_artist) !== false) {
|
||||
$weight += 4;
|
||||
}
|
||||
|
||||
if ($file['track'] == $this->_track) {
|
||||
$weight += 10;
|
||||
} elseif (strpos($file['track'], $this->_track) !== false) {
|
||||
$weight += 5;
|
||||
}
|
||||
|
||||
if ($file['duration'] == $this->_duration) {
|
||||
$weight += 10;
|
||||
} else {
|
||||
$delta = abs($file['duration'] - $this->_duration);
|
||||
if ($delta < 5) {
|
||||
$weight += (5 - $delta);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_files[$i]['weight'] = $weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
/*****************************************************************
|
||||
Пример использования:
|
||||
|
||||
$vk_parser = new Vkontakte($bot_name);
|
||||
$vk_parser->parse('Blondie - Call Me');
|
||||
$files = $vk_parser->getFiles();
|
||||
*****************************************************************/
|
||||
|
||||
/**
|
||||
* Класс парсинга вконтактика
|
||||
*
|
||||
* @package classes
|
||||
* @author chez
|
||||
**/
|
||||
class Vkontakte {
|
||||
|
||||
private $_cookies; // Куки, ассоциативный массив
|
||||
private $_query; // Запрос, plain text
|
||||
|
||||
private $_html; // HTML, полученый от вконтактика
|
||||
private $_files; // Распарсеные массивы с информацией о файле
|
||||
|
||||
private $_bot_info; // Информация о боте
|
||||
|
||||
public function __construct($bot_name = false) {
|
||||
if ($bot_name) {
|
||||
$this->_bot_info = Config::get('bot:'. $bot_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Оболочка парсера
|
||||
*
|
||||
* @param string $q Запрос
|
||||
* @return array Массив с файлами
|
||||
* @author chez
|
||||
**/
|
||||
public function getTracks($q) {
|
||||
$this->_query = $q;
|
||||
$this->auth();
|
||||
$cookie = array();
|
||||
foreach ($this->_cookies as $key => $val) {
|
||||
$cookie[] = $key .'='. $val;
|
||||
}
|
||||
RemoteFile::setHeaders(array(
|
||||
'Cookie: '. implode('; ', $cookie),
|
||||
'Referer: http://vkontakte.ru/audio?album_id=0',
|
||||
'X-Requested-With: XMLHttpRequest',
|
||||
'Origin: http://vkontakte.ru',
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
'User-Agent: '. $this->_bot_info['user_agent'],
|
||||
'Connection: close'
|
||||
));
|
||||
$html = RemoteFile::getData('http://vkontakte.ru/audio', array(
|
||||
'act' => 'search',
|
||||
'al' => '1',
|
||||
'gid' => '0',
|
||||
'id' => $this->_bot_info['user_id'],
|
||||
'offset' => '0',
|
||||
'q' => urlencode($this->_query),
|
||||
'sort' => '2'
|
||||
));
|
||||
$this->setHtml($html);
|
||||
return (strlen($html) > 150);
|
||||
}
|
||||
|
||||
/**
|
||||
* Пишет полученый html в член объекта
|
||||
*
|
||||
* @param string $html HTML
|
||||
* @return void
|
||||
* @author chez
|
||||
**/
|
||||
public function setHtml($html) {
|
||||
$this->_html = $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает хранимый html
|
||||
*
|
||||
* @return string HTML
|
||||
* @author chez
|
||||
**/
|
||||
public function getHtml() {
|
||||
return $this->_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает хранимый массив файлов
|
||||
*
|
||||
* @return array Список файлов
|
||||
* @author chez
|
||||
**/
|
||||
public function getFiles() {
|
||||
return $this->_files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проводит авторизацию на вконтактике и получает куки
|
||||
* Пока костыль, потом нужно будет переписать
|
||||
*
|
||||
* @return array Ассоциативный массив с куками
|
||||
* @author chez
|
||||
**/
|
||||
private function auth() {
|
||||
$this->_cookies = array(
|
||||
'remixchk' => $this->_bot_info['remixchk'],
|
||||
'remixsid' => $this->_bot_info['remixsid'],
|
||||
'remixlang' => 777
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Разбирает HTML, полученый от вконтактика
|
||||
*
|
||||
* @return array Список файлов
|
||||
* @author chez
|
||||
**/
|
||||
public function parseHtml() {
|
||||
preg_match_all('/<tr>(.*)<\/tr>/Usi', $this->_html, $m);
|
||||
$files = array();
|
||||
if (count($m) > 0) foreach ($m[0] as $res) {
|
||||
$m1 = array();
|
||||
preg_match('/<input.*value=\"(.*)\,(\d{2,4})\".*<div\sclass=\"duration.*>(.*)<\/div>.*<a.*>(.*)<\/a>.*\s-\s(.*)<\/div>/Usi', $res, $m1);
|
||||
if (count($m1) > 0) {
|
||||
$duration = explode(':', $m1[3]);
|
||||
$files[] = array(
|
||||
'url' => $m1[1],
|
||||
'duration' => $duration[0] * 60 + $duration[1],
|
||||
'artist' => strip_tags($m1[4]),
|
||||
'track' => strip_tags($m1[5])
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->_files = $files;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/*****************************************************************
|
||||
Пример использования:
|
||||
|
||||
$files = VkontakteMP3::check($files);
|
||||
*****************************************************************/
|
||||
|
||||
/**
|
||||
* Класс для постобработки массива треков от контакта
|
||||
* Проверяет файлы, рассчитывает битрейт и релевантность
|
||||
*
|
||||
* @package classes
|
||||
* @author chez
|
||||
**/
|
||||
class VkontakteMP3 {
|
||||
|
||||
private static $_bitrates = array( // Массив стандартных битрейтов
|
||||
8, 16, 24, 32, 40, 48, 56,
|
||||
64, 80, 96, 112, 128, 144,
|
||||
160, 192, 224, 256, 320
|
||||
);
|
||||
|
||||
/**
|
||||
* Рассчитывает средний битрейт файла
|
||||
* Приводит полученый битрейт к одному из стандартных
|
||||
*
|
||||
* @param int $size Размер файла в байтах
|
||||
* @param int $length Длина трека в секундах
|
||||
* @return int Битрейт в килобитах в секунду
|
||||
* @author chez
|
||||
**/
|
||||
public static function calculateBitrate($size, $length) {
|
||||
$br = round($size * 8 / 1024 / $length);
|
||||
$found_br = 0;
|
||||
for ($i = 1; $i < count(self::$_bitrates); $i++) {
|
||||
if (self::$_bitrates[$i] > $br && ! $found_br) {
|
||||
$delta = self::$_bitrates[$i] - $br;
|
||||
$br_delta = self::$_bitrates[$i] - self::$_bitrates[$i-1];
|
||||
if (round($br_delta / 3) > $delta) {
|
||||
$found_br = self::$_bitrates[$i];
|
||||
} else {
|
||||
$found_br = self::$_bitrates[$i-1];
|
||||
}
|
||||
} elseif ($i == count(self::$_bitrates) - 1 && self::$_bitrates[$i] < $br && ! $found_br) {
|
||||
$delta = $br - self::$_bitrates[$i];
|
||||
if ($delta < 32) {
|
||||
$found_br = self::$_bitrates[$i];
|
||||
} else {
|
||||
$found_br = $br;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $found_br;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет файлы, рассчитывает битрейт и релевантность
|
||||
*
|
||||
* @param array $files Массив файлов для обработки
|
||||
* @return array Обработанный массив файлов
|
||||
* @author chez
|
||||
**/
|
||||
public static function check($files, $artist_name, $track_name, $track_length) {
|
||||
$urls = array();
|
||||
foreach($files as $i => $file) {
|
||||
$urls[$i] = $file['url'];
|
||||
}
|
||||
$headers = RemoteFile::getHeadersMT($urls);
|
||||
foreach ($files as $i => $file) {
|
||||
if (!isset($headers[$i]['http']) || $headers[$i]['http'] != 200) {
|
||||
unset($files[$i]);
|
||||
} else {
|
||||
$files[$i]['size'] = trim($headers[$i]['content_length']);
|
||||
}
|
||||
}
|
||||
$m = new TrackWeight();
|
||||
$m->setTrackData($artist_name, $track_name, $track_length);
|
||||
$m->setFiles($files);
|
||||
$m->calculateWeight();
|
||||
$files = $m->getFiles();
|
||||
|
||||
uasort($files, function($a, $b){
|
||||
return $a['weight'] < $b['weight'];
|
||||
});
|
||||
|
||||
foreach ($files as $i => $file) {
|
||||
$files[$i]['bitrate'] = self::calculateBitrate($file['size'], $files[$i]['duration']);
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Чистит строку для максимально точного сравнения
|
||||
*
|
||||
* @param string $str Необработанная строка
|
||||
* @return string Чистая строка
|
||||
* @author chez
|
||||
**/
|
||||
public static function prepareQuery($str) {
|
||||
$str = trim($str);
|
||||
while(strpos($str, ' ') !== false) {
|
||||
$str = str_replace(' ', ' ', $str);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразует длину из формата мм:сс в ссс
|
||||
*
|
||||
* @param string $duration Читабельная длина
|
||||
* @return int Длина в секундах
|
||||
* @author chez
|
||||
**/
|
||||
public static function convertDuration($duration) {
|
||||
$tmp = explode(':', $duration);
|
||||
return ($tmp[0] * 60 + $tmp[1]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
// 123456 --> /www/beatdb/1/2/3/4/5/123456.json
|
||||
|
||||
class BeatDB {
|
||||
|
||||
private static $_db_root = '/www/beatdb/';
|
||||
|
||||
public static function get($key) {
|
||||
if (self::exists($key)) {
|
||||
return json_decode(
|
||||
file_get_contents(
|
||||
self::$_db_root . implode('/', self::getFilePathByKey($key))
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function set($key, $data) {
|
||||
$path = self::getFilePathByKey($key);
|
||||
$part = self::$_db_root;
|
||||
for ($i = 0; $i < count($path) - 1; $i++) {
|
||||
$part .= $path[$i] .'/';
|
||||
}
|
||||
if (!file_exists($part)) {
|
||||
if (!mkdir($part, 0777, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
file_put_contents($part . $path[$i], json_encode($data));
|
||||
chmod($part . $path[$i], 0777);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function delete($key) {
|
||||
$path = self::getFilePathByKey($key);
|
||||
$ret = array();
|
||||
for ($i = count($path) - 1; $i >= 0; $i--) {
|
||||
$part = self::$_db_root . implode('/', $path);
|
||||
unset($path[$i]);
|
||||
if (is_file($part)) {
|
||||
unlink($part);
|
||||
} elseif (count(scandir($part)) == 2) {
|
||||
rmdir($part);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function exists($key) {
|
||||
return file_exists(self::$_db_root . implode('/', self::getFilePathByKey($key)));
|
||||
}
|
||||
|
||||
private static function getFilePathByKey($key) {
|
||||
$key = strval($key);
|
||||
$path = array();
|
||||
for ($i = 0; $i < strlen($key) - 1; $i++) {
|
||||
$path[] = substr($key, $i, 1);
|
||||
}
|
||||
$path[] = $key .'.json';
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
class Db extends Singleton {
|
||||
|
||||
private $_driver;
|
||||
|
||||
public function init() {
|
||||
$params = Config::get('app:DB');
|
||||
$driver = $params['engine'];
|
||||
unset($params['engine']);
|
||||
switch ($driver) {
|
||||
case 'pgsql' : default :
|
||||
$this->_driver = new Pgsql(); break;
|
||||
}
|
||||
call_user_func_array(array($this->_driver, 'connect'), $params);
|
||||
}
|
||||
|
||||
public function q($q, $params = array()) {
|
||||
if (! $this->_driver) {
|
||||
$this->init();
|
||||
}
|
||||
return $this->_driver->q($q);
|
||||
}
|
||||
|
||||
public function getRows($result, $key = false) {
|
||||
if (! $this->_driver) {
|
||||
$this->init();
|
||||
}
|
||||
return $this->_driver->getRows($result, $key);
|
||||
}
|
||||
|
||||
public function getRow($result) {
|
||||
if (! $this->_driver) {
|
||||
$this->init();
|
||||
}
|
||||
return $this->_driver->getRow($result);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
class Pgsql implements iDbDriver {
|
||||
|
||||
private $_connection = false;
|
||||
|
||||
public function connect($host, $port, $dbname, $login, $pass) {
|
||||
$this->connection = pg_connect('host='. $host .' port='. $port .' dbname='. $dbname .' user='. $login .' password='. $pass);
|
||||
}
|
||||
|
||||
public function q($q) {
|
||||
return pg_query($q);
|
||||
}
|
||||
|
||||
public function getRows($r, $key = false) {
|
||||
$rows = array();
|
||||
while($row = pg_fetch_assoc($r)) {
|
||||
if (!$key) {
|
||||
$rows[] = $row;
|
||||
} else {
|
||||
$rows[$row[$key]] = $row;
|
||||
}
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function getRow($r) {
|
||||
return pg_fetch_assoc($r);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
interface iDbDriver {
|
||||
|
||||
public function connect($host, $port, $dbname, $login, $pass);
|
||||
|
||||
public function q($q);
|
||||
|
||||
public function getRows($r, $key);
|
||||
|
||||
public function getRow($r);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
class Cloud {
|
||||
|
||||
private $_wrapper;
|
||||
|
||||
public function __construct() {
|
||||
$params = Config::get('app:CloudApp');
|
||||
$this->_wrapper = new Cloud_API($params['login'], $params['pass']);
|
||||
}
|
||||
|
||||
public function getFiles() {
|
||||
$files = $this->_wrapper->getItems();
|
||||
var_dump($files);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
/*****************************************************************
|
||||
Пример использования:
|
||||
|
||||
RemoteFile::setHeaders(array(
|
||||
'X-Requested-With: XMLHttpRequest',
|
||||
'Origin: http://vkontakte.ru',
|
||||
'Content-Type: application/x-www-form-urlencoded'
|
||||
));
|
||||
$headers = RemoteFile::getHeaders('http://cs4603.vkontakte.ru/u50132690/audio/432e2b109b94.mp3');
|
||||
$html = RemoteFile::getData('http://vkontakte.ru/audio', array(
|
||||
'act' =>'search',
|
||||
'q' => urlencode($this->_query)
|
||||
))
|
||||
*****************************************************************/
|
||||
|
||||
/**
|
||||
* Класс для работы с удаленными файлами
|
||||
* Реализован через библиотеку cURL
|
||||
*
|
||||
* @package classes
|
||||
* @author chez
|
||||
**/
|
||||
class RemoteFile {
|
||||
|
||||
private static $_timeout = 5; // Таймаут ответа от сервера
|
||||
private static $_headers = array(); // Заголовки для отправки на сервер
|
||||
|
||||
/**
|
||||
* Отправка запроса и получение ответа от сервера
|
||||
* Умеет возвращать текст ответа или заголовки
|
||||
*
|
||||
* @param string $url URL запроса
|
||||
* @param bool $headers Флаг: возвращать заголовки, а не текст
|
||||
* @param array $post_params Массив POST-параметров, если установлен, то метод меняется на POST
|
||||
* @return string Ответ от сервера
|
||||
* @author chez
|
||||
**/
|
||||
private static function _exec($url, $headers = false, $post_params = array()) {
|
||||
if (count($post_params) > 0) {
|
||||
$p = '';
|
||||
foreach ($post_params as $key => $val) {
|
||||
$p .= '&'. $key .'='. $val;
|
||||
}
|
||||
$post_params = substr($p, 1);
|
||||
}
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, self::$_headers);
|
||||
if ($headers) {
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, 1);
|
||||
}
|
||||
if (is_string($post_params)) {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$_timeout);
|
||||
$result = curl_exec($ch);
|
||||
if (curl_errno($ch) !== 0) {
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
curl_close($ch);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение HTTP-заголовков ответа от сервера
|
||||
*
|
||||
* @param string $url URL запроса
|
||||
* @param array $post_params Массив POST-параметров, если установлен, то метод меняется на POST
|
||||
* @return array Распарсеный массив заголовков
|
||||
* @author chez
|
||||
**/
|
||||
public static function getHeaders($url, $post_params = array()) {
|
||||
$headers = self::_exec($url, true);
|
||||
if ($headers === false) {
|
||||
return false;
|
||||
}
|
||||
$headers = explode("\r\n", $headers);
|
||||
$headers_array = array();
|
||||
|
||||
while(list($i, $header) = each($headers)) {
|
||||
if (substr($header, 0, 5) == 'HTTP/') {
|
||||
$header = explode(' ', $header);
|
||||
$headers_array['http'] = $header[1];
|
||||
} elseif ($header != '') {
|
||||
preg_match('/^([a-z0-9\-]*):\s(.*)$/Ui', $header, $m);
|
||||
$headers_array[strtolower(str_replace('-', '_', $m[1]))] = $m[2];
|
||||
}
|
||||
}
|
||||
|
||||
return $headers_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение ответа от сервера
|
||||
*
|
||||
* @param string $url URL запроса
|
||||
* @param array $post_params Массив POST-параметров, если установлен, то метод меняется на POST
|
||||
* @return string Тело ответа от сервера
|
||||
* @author chez
|
||||
**/
|
||||
public static function getData($url, $post_params = array()) {
|
||||
return self::_exec($url, false, $post_params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись заголовков, которые будет отправлены вместе с запросом
|
||||
*
|
||||
* @param array $headers Индексный массив заголовков
|
||||
* @return void
|
||||
* @author chez
|
||||
**/
|
||||
public static function setHeaders($headers) {
|
||||
self::$_headers = $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Массововое получение заголовков по списку файлов
|
||||
*
|
||||
* @param array $fules Ассоциативный массив id => url
|
||||
* @return array Ассоциативный массив id => headers
|
||||
* @author chez
|
||||
**/
|
||||
public static function getHeadersMT($files) {
|
||||
$mh = curl_multi_init();
|
||||
$headers_all = array();
|
||||
$handlers = array();
|
||||
foreach($files as $i => $url) {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_multi_add_handle($mh, $ch);
|
||||
$handlers[$i] = $ch;
|
||||
}
|
||||
$running=null;
|
||||
do
|
||||
{
|
||||
curl_multi_exec($mh, $running);
|
||||
usleep (500000);
|
||||
} while ($running > 0);
|
||||
foreach($handlers as $i => $ch) {
|
||||
$content = curl_multi_getcontent($handlers[$i]);
|
||||
curl_multi_remove_handle($mh, $handlers[$i]);
|
||||
$content = explode("\r\n", $content);
|
||||
$headers = array();
|
||||
foreach($content as $header) {
|
||||
if (substr($header, 0, 5) == 'HTTP/') {
|
||||
$header = explode(' ', $header);
|
||||
$headers['http'] = $header[1];
|
||||
} elseif ($header != '') {
|
||||
preg_match('/^([a-z0-9\-]*):\s(.*)$/Ui', $header, $m);
|
||||
$headers[strtolower(str_replace('-', '_', $m[1]))] = $m[2];
|
||||
}
|
||||
}
|
||||
$headers_all[$i] = $headers;
|
||||
}
|
||||
curl_multi_close($mh);
|
||||
return $headers_all;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
class Controller {
|
||||
|
||||
public function loadPage() {
|
||||
$app = Config::get('app:App:default_app');
|
||||
|
||||
require_once 'app/'. $app .'/controllers/Index.class.php';
|
||||
$c = new IndexController();
|
||||
$data = $c->_index();
|
||||
|
||||
$v = new View();
|
||||
$v->setTemplate('app/'. $app .'/templates/main.php');
|
||||
$v->setView('app/'. $app .'/views/Index_index.php');
|
||||
$v->setData($data);
|
||||
|
||||
$html = $v->render();
|
||||
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
echo $html;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
class Model {
|
||||
|
||||
protected $db;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = Db::getInstance();
|
||||
}
|
||||
|
||||
public static function factory($package, $model) {
|
||||
require_once ROOT_DIR .'/app/'. $package .'/models/'. $model .'.class.php';
|
||||
$class_name = ucfirst($package) .'_'. $model .'Model';
|
||||
return new $class_name();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
class View {
|
||||
|
||||
private $_template;
|
||||
private $_view;
|
||||
private $_data;
|
||||
|
||||
private $_block;
|
||||
|
||||
public function setTemplate($path) {
|
||||
$this->_template = $path;
|
||||
}
|
||||
|
||||
public function setView($path) {
|
||||
$this->_view = $path;
|
||||
}
|
||||
|
||||
public function setData($data) {
|
||||
$this->_data = $data;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$this->_block = $this->_sandbox($this->_view);
|
||||
return $this->_sandbox($this->_template);
|
||||
}
|
||||
|
||||
private function _sandbox($path) {
|
||||
ob_clean();
|
||||
include $path;
|
||||
$html = ob_get_contents();
|
||||
ob_clean();
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
abstract class Singleton {
|
||||
|
||||
protected function __construct() {}
|
||||
|
||||
final public static function getInstance() {
|
||||
static $_instances = array();
|
||||
|
||||
$class_name = get_called_class();
|
||||
|
||||
if (! isset($_instances[$class_name])) {
|
||||
$_instances[$class_name] = new $class_name();
|
||||
}
|
||||
|
||||
return $_instances[$class_name];
|
||||
}
|
||||
|
||||
final private function __clone() {}
|
||||
}
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
/www/cloudapp/Cloud/
|
||||
Reference in New Issue
Block a user