Location: PHPKode > projects > Simple Way to Usenet > libs/swun/search/newzbin/nb_fetch.class.php
<?php
/**
 *  
 * @author  Benjamin Gillissen <hide@address.com>
 * 
 *	**************************************************************

	Copyright (C) 2009  Benjamin Gillissen
	
	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details at:
	http://www.gnu.org/copyleft/gpl.html

 *	**************************************************************
 */
class nb_fetch {

	private static $isconn;		//bool to know if curl is available
	private static $cookfile;	//path to session cookfile
	private static $sesslifetime = 600; //10minutes in secondes
	private static $curl;		//the curl resource.
	private static $islogged;	//bool to know if login was ok

	
	
	//check if curl is ok, init curl ressource, set some curl options
	private static function connect(){
		if ( ! CORE::isphpModLoaded('curl') ){
			if ( ! CORE::LoadphpMod('curl') ){
				errors::raise('NewzBin.com Fetcher (nb_fetch) require PHP Curl extension, please contact your system adminsitrator.', CORE_LOG_ALERT, 'NB_FETCH'); 
			}
		}
		if ( isset(self::$isconn) ){ return self::$isconn; }
		if ( !chrono::isinit('nb_fetch') ){ chrono::init('nb_fetch'); }
		self::$cookfile = realpath(PATH_CACHE).'/newzbin_cooky.txt';
		$hdl = @fopen(self::$cookfile, 'a+');
		if ( FALSE === $hdl ){
			errors::raise('Connection to NewzBin.com aborded, cooky file could not be created at '.self::$cookfile, CORE_LOG_ERROR, 'NB_FETCH');
			self::$isconn = FALSE;return FALSE;
		}
		self::$curl = curl_init();
    	curl_setopt(self::$curl, CURLOPT_USERAGENT, 'swun');
    	curl_setopt(self::$curl, CURLOPT_COOKIEFILE, self::$cookfile);
    	curl_setopt(self::$curl, CURLOPT_COOKIEJAR, self::$cookfile);
    	curl_setopt(self::$curl, CURLOPT_SSL_VERIFYHOST, 0);
    	curl_setopt(self::$curl, CURLOPT_ENCODING , "gzip");
		self::$isconn = TRUE;return TRUE;
	}
	
	//do a post query on login form page
	public static function login($force=FALSE){
		if ( ! self::connect() ){ return FALSE; }
		if ( $force === FALSE ){
			if ( self::is_loged() ){ return TRUE; }
			if ( isset(self::$islogged) ){ return FALSE; }		
		}
		$chr = chrono::start('nb_fetch');
		$post['username'] = configs::get('newzbinv2', 'user');
		$post['password'] = configs::get('newzbinv2', 'pass');
		//recode postvar
		$o="";
		foreach ($post as $k=>$v){ $o.= "$k=".utf8_encode($v)."&"; }
    	$post=substr($o,0,-1);
		curl_setopt(self::$curl, CURLOPT_POST, 1);
    	curl_setopt(self::$curl, CURLOPT_HEADER, 0);
    	curl_setopt(self::$curl, CURLOPT_REFERER, search_nbrid::base_url.'account/login/');
    	curl_setopt(self::$curl, CURLOPT_URL, search_nbrid::base_url.'account/login/');   
    	curl_setopt(self::$curl, CURLOPT_POSTFIELDS, $post);
    	curl_setopt(self::$curl, CURLOPT_RETURNTRANSFER, 1);
    	$file = CORE::tempfile();
		$dst = fopen($file, 'w');
		if ( FALSE === $dst ){ 
			errors::raise('NewzBin.com destination file could not be created, probably no valid temp folder detected by core::tempfile()', CORE_LOG_ERROR, 'NB_FETCH');
			chrono::pause('nb_fetch', $chr);
			return FALSE;
		}
		curl_setopt(self::$curl, CURLOPT_FILE, $dst);
		$result = @curl_exec(self::$curl);
    	if ( 0 != curl_errno(self::$curl) ){ 
    		errors::raise('Login to NewzBin.com failed : curl error, '.curl_error(self::$curl), CORE_LOG_ERROR, 'NB_FETCH');
    		self::$islogged = FALSE;
			chrono::pause('nb_fetch', $chr);
    		return FALSE; 
    	}
    	$err = self::check_parse_error($file);
		if ( $err !== TRUE ){
			errors::raise('Login to Newzbin.com Failed : '.$err, CORE_LOG_ERROR, 'NB_FETCH');
			unlink($file);
			self::$islogged = FALSE;
    		chrono::pause('nb_fetch', $chr);
    		return FALSE;
		}
		unlink($file);
    	errors::raise('Login success to NewzBin.com', CORE_LOG_NOTICE, 'NB_FETCH');
    	self::$islogged = TRUE;
		chrono::pause('nb_fetch', $chr);
    	return TRUE;
	}
	
	//tell if the loged session on newzbin.com is still 
	public static function is_loged(){
		if ( isset(self::$islogged) ){ return self::$islogged; }
		if ( !file_exists(self::$cookfile) ){ return FALSE;	}
		return ( filemtime(self::$cookfile) >= (time()-self::$sesslifetime) );
	}
	
	public static function normalize_report(&$data){
		$data['gotdetails'] = TRUE;
		$data['imdbid'] = '';
		if ( isset($data['moreinfo']) ){
			if ( ereg('imdb.com', $data['moreinfo']) ){
				$tmp = split('imdb.com/title/tt', $data['moreinfo']);
				if ( isset($tmp[1]) ){ $data['imdbid'] = str_replace('/', '', $tmp[1]); }
				unset($tmp);
			}
			$data['moreinfo'] = str_replace("&", "&amp;", $data['moreinfo']);
			//$data['moreinfo'] = str_replace('http://', '', $data['moreinfo']);
			//$data['moreinfo'] = 'http://'.rawurlencode($data['moreinfo']);
		} else {
			$data['moreinfo'] = '';
		}
		
		if ( isset($data['progress']) ){
			if ( $data['progress'] == 'Report is complete' ){				$data['status'] = 'complete';
			} elseif ( $data['progress'] == 'Report is still uploading' ){	$data['status'] = 'uploading';
			} elseif ( $data['progress'] == 'Report is incomplete' ){		$data['status'] = 'incomplet';
			} else {														$data['status'] = 'unknow';		}
		} else {														
			$data['status'] = 'notset';	
		}
		
		if ( isset($data['postdate']) ){
			$month = Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
			$buf = split(' ', $data['postdate']);
			$data['date'] = mktime( 0, 0, 0, (array_search($buf[2], $month)+1), $buf[1], $buf[3]);
			unset($buf, $data['postdate']);
		}
		
		if ( is_array($data['groups']) ){
			foreach($data['groups'] as $k => &$grp){
				$grp = str_replace('alt.binaries.', 'a.b.', $grp);
			}
		}
		
		if ( is_array($data['attributes']) ){
			foreach($data['attributes'] as $k => &$attribs){
				foreach($attribs as $n => &$attr){ $attr = htmlentities($attr, ENT_QUOTES); }
			}
		}
		return $data;
	}
	
	//do a http authed request on RSS Feed and store result into a file, return tmp filename, or FALSE
	public static function request($url, $auth=FALSE){
		if ( $auth ){ 
			if ( ! self::login(FALSE) ){ 
				errors::raise('We are not loged to NewzBin.com, and request need auth, we keep going but without attributes', CORE_LOG_WARNING, 'NB_FETCH');
			}
		} elseif ( ! self::connect() ){ 
			errors::raise('Connection Failure, trouble with curl ?', CORE_LOG_ERROR, 'NB_FETCH');
			return FALSE; 
		}
		$chr = chrono::start('nb_fetch');
		$file = CORE::tempfile();
		$dst = fopen($file, 'w');
		if ( FALSE === $dst ){ 
			errors::raise('NewzBin.com search destination file could not be created, probably no valid temp folder detected by core::tempfile()', CORE_LOG_ERROR, 'NB_FETCH');
			chrono::pause('nb_fetch', $chr);
			curl_close(self::$curl);
			return FALSE;
		}
		curl_setopt(self::$curl, CURLOPT_REFERER, '');
		curl_setopt(self::$curl, CURLOPT_RETURNTRANSFER, 0);
		curl_setopt(self::$curl, CURLOPT_POST, 0);
    	curl_setopt(self::$curl, CURLOPT_HEADER, 0);
		curl_setopt(self::$curl, CURLOPT_URL, $url);
		curl_setopt(self::$curl, CURLOPT_FILE, $dst);
		$result = @curl_exec(self::$curl);
		if ( 0 != curl_errno(self::$curl) ){ 
			errors::raise('Newzbin.com RSS Feed Request Failed : curl error, '.curl_error(self::$curl), CORE_LOG_ERROR, 'NB_FETCH');
			curl_close(self::$curl);
			chrono::pause('nb_fetch', $chr);
    		return FALSE; 
		}
		curl_setopt(self::$curl, CURLOPT_REFERER, $url);
		fclose($dst);
		$err = self::check_parse_error($file);
		if ( $err !== TRUE ){
			errors::raise('Newzbin.com RSS Feed Request Failed : '.$err, CORE_LOG_ERROR, 'NB_FETCH');
			unlink($file);
			chrono::pause('fetch', $chr);
			return FALSE;
		}
		chrono::pause('nb_fetch', $chr);
		return $file;
	}
	
	private static function check_parse_error($file){
		$c = file_get_contents($file);
		if ( ! ereg("Error", $c) ){ return TRUE; }
		$XML = new XMLReader();
		if ( FALSE === $XML->open( $file ) ){
			unset($XML);
			$buf = split('><span>Error:</span>', $c);
			if ( !isset($buf[1]) ){ file_put_contents(PATH_CACHE.'/nb_reply.html', $c); }
			$err = split("</li>", $buf[1]);
		} else {
			$XML->setParserProperty(XMLReader::LOADDTD,  FALSE);
			$XML->setParserProperty(XMLReader::VALIDATE, FALSE);
			$err = '?';
			while ( $XML->read() ){
				if ( $XML->nodeType == XMLReader::CDATA ){ $err = $XML->value;break; }
			}
			$XML->close();
			unset($XML);
		}
		return $err;
	}
	
	//to dload a nzb file from nb.
	public static function getnfo($txtid, $filename='truc'){
		if ( ! self::login() ){ return FALSE; }
		$chr = chrono::start('nb_fetch'); 
		$post['n_filename'] = $filename;
		$post['save_nfo_as'] = 'Save NFO As..';
		curl_setopt(self::$curl, CURLOPT_REFERER, '');
		curl_setopt(self::$curl, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt(self::$curl, CURLOPT_POST, 1);
		curl_setopt(self::$curl, CURLOPT_HEADER, 0);
		curl_setopt(self::$curl, CURLOPT_URL, search_nbrid::base_url.'nfo/view/png/'. $txtid . '/');
    	curl_setopt(self::$curl, CURLOPT_POSTFIELDS, $post);
		$result = curl_exec(self::$curl);
		if ( 0 != curl_errno(self::$curl) ){ 
			errors::raise('NewzBin.com NFO Request Failed : curl error, '.curl_error(self::$curl), CORE_LOG_ERROR, 'NB_FETCH');
			chrono::pause('nb_fetch', $chr);
    		return FALSE; 
		}
		curl_close(self::$curl);
		chrono::pause('nb_fetch', $chr);
		return $result;
	}
	
	//to dload a nzb file from nb directID
	public static function get_nzb($nbrid, $fileids=NULL){
		$file = CORE::tempfile();
		$dst = fopen($file, 'w');
		if ( FALSE === $dst ){ 
			errors::raise('NewzBin.org nzb destination file could not be created, probably no valid temp folder detected by core::tempfile()', CORE_LOG_ERROR, 'NB_FETCH');
			curl_close(self::$curl);
			return FALSE;
		}
		if ( $fileids !== NULL ){
			$post['fileid'] = implode(',', $fileids);
		} else {
			$post['reportid'] = $nbrid;
		}
		errors::raise('DirectID call with : '.print_r($post, TRUE), CORE_LOG_NOTICE, 'NB_FETCH');
		$post['username'] = configs::get('newzbinv2', 'user');
		$post['password'] = configs::get('newzbinv2', 'pass');
    	$curl = curl_init();
    	curl_setopt($curl, CURLOPT_USERAGENT, 'swun');
    	curl_setopt($curl, CURLOPT_REFERER, '');
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 0);
		curl_setopt($curl, CURLOPT_POST, 1);
    	curl_setopt($curl, CURLOPT_HEADER, 1);
		curl_setopt($curl, CURLOPT_URL, 'http://v3.newzbin.com/api/dnzb/');
		@curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
		curl_setopt($curl, CURLOPT_FILE, $dst);
		$result = @curl_exec($curl);
		if ( 0 != curl_errno($curl) ){ 
			errors::raise('Curl error for NZB Request on NewzBin.org : '.curl_error($curl), CORE_LOG_ERROR, 'NB_FETCH');
			curl_close($curl);
    		return FALSE; 
		}
		$hsize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
		curl_close($curl);
		fclose($dst);
		$src = fopen($file, 'r');
		$headers = fread($src, $hsize);
		$headers = split("\n", $headers);
		foreach($headers as $k => &$header){
			if ( ereg('X-DNZB-RCode: 200', $header) ){
				$nfile = CORE::tempfile();
				$dst = fopen($nfile, 'w');
				while( FALSE !== ($line = fgets($src)) ){ fputs($dst, $line); }
				fclose($src);unlink($file);
				fclose($dst);
				return $nfile; 
			}
			if ( ereg('X-DNZB-RCode: 400', $header) ){ errors::raise("Newzbin.com : missing parameters", CORE_LOG_ERROR, 'NB_FETCH');break; }
			if ( ereg('X-DNZB-RCode: 401', $header) ){ errors::raise("Newzbin.com : auth failure", CORE_LOG_ERROR, 'NB_FETCH');break; }
			if ( ereg('X-DNZB-RCode: 402', $header) ){ errors::raise("Newzbin.com : payment required", CORE_LOG_ERROR, 'NB_FETCH');break; }
			if ( ereg('X-DNZB-RCode: 404', $header) ){ errors::raise("Newzbin.com : DirectID returned no result", CORE_LOG_NOTICE, 'NB_FETCH');break; }
			if ( ereg('X-DNZB-RCode: 450', $header) ){ errors::raise("Newzbin.com : max rate reached", CORE_LOG_NOTICE, 'NB_FETCH');break; }
			if ( ereg('X-DNZB-RCode: 500', $header) ){ errors::raise("Newzbin.com : DirectID is down !", CORE_LOG_ERROR, 'NB_FETCH');break; }
			if ( ereg('X-DNZB-RCode: 503', $header) ){ errors::raise("Newzbin.com : down for maintenance!", CORE_LOG_ERROR, 'NB_FETCH');break; }
		}
		unlink($file);
		return FALSE;
	}
}
return TRUE;
Return current item: Simple Way to Usenet