blob: 7302cd1931d2fa4f4311b0abbf164d316966ada4 [file] [log] [blame]
<?php
################################################################
# NAME: news.class.php #
# AUTHOR: Diego Figueroa #
# DESC: Implementation of methods to access newsgroups. This #
# is not a complete/standard implementation of RFC 977 #
# http://www.w3.org/Protocols/rfc977/rfc977.html #
# DATE: Aug 31, 2005 #
# LAST MOD: Sep 1, 2005 #
# #
# REQUIRES: config.php #
################################################################
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/stats/responses.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/stats/utils.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/stats/post.class.php");
class GInfo {
var $_ginfo;
function GInfo(){
$this->_ginfo = array();
}
function setInfo($info){
$this->_ginfo = $info;
}
function getNumberPosts(){
return $this->_ginfo[0];
}
function getFirstPost(){
return $this->_ginfo[1];
}
function getLastPost(){
return $this->_ginfo[2];
}
function getNewsGroupName(){
return $this->_ginfo[3];
}
}
class News {
var $_handle;
# Constructor
function News(){
$this->_handle = 0;
}
function perror($text){
print $text."<br>\n";
exit();
}
function warning($text){
# print $text."<br>\n"; // Only on when debugging
}
function response($code){
return substr($code,0,RESPONSE_LENGTH);
}
function connect($server,$port,$timeout){
$this->_handle = fsockopen($server, $port, $errno, $errstr, $timeout);
if (!$this->_handle)
$this->perror("Connection failed");
else {
echo "Connected\n";
$tmp = fgets($this->_handle, 1024);
print $tmp."\n";
}
}
function disconnect(){
fputs($this->_handle, "QUIT\n");
$tmp = fgets($this->_handle, 1024);
if ($this->response($tmp) != R205)
$this->perror("Error while disconnecting from server");
}
function authenticate($user,$pass){
if (!$this->_handle)
$this->perror("Invalid handle");
fputs($this->_handle, "AUTHINFO USER ".$user."\n");
$tmp = fgets($this->_handle, 1024);
fputs($this->_handle, "AUTHINFO PASS ".$pass."\n");
$tmp = fgets($this->_handle, 1024);
if ($tmp != "281 Ok\r\n")
$this->perror("502 Authentication error");
}
function getGroups(){
$groups = array();
fputs($this->_handle, "LIST\n");
$tmp = fgets($this->_handle, 1024);
if ($this->response($tmp) != R215)
$this->perror($tmp);
while($tmp != '.'){ # As defined in RFC 977
$tmp = substr(fgets($this->_handle, 1024),0,-2);
if ($tmp != '.')
array_push($groups,substr($tmp,0,strpos($tmp,' ')));
}
return $groups;
}
function selectGroup($gname){
$ginfo = new GInfo();
fputs($this->_handle, "GROUP ".$gname."\n");
$tmp = fgets($this->_handle, 1024);
if ($this->response($tmp) != R211){
$this->warning($tmp);
$ginfo->setInfo(array(0,0,0,-1));
return $ginfo;
}
$tmp = substr($tmp,RESPONSE_LENGTH+1); # Remove response
$ginfo->setInfo(explode(" ",$tmp));
return $ginfo; # [num. posts | First | Last | newsgroup]
}
function getPostHead($article){
$head = array();
fputs($this->_handle, "HEAD ".$article."\n");
$tmp = fgets($this->_handle, 1024);
if ($this->response($tmp) != R221){ # If not a valid post
$tmp = substr($tmp,0,-2); # Remove 'new line' char
$this->warning($tmp.". Article: $article\n");
return (new Post(array()));
}
while($tmp != '.'){ # As defined in RFC 977
$tmp = substr(fgets($this->_handle, 1024),0,-2);
if ($tmp != '.')
array_push($head,$tmp);
}
return (new Post($head));
}
function numPosts($group){
$tmp = select_group($this->_handle,$group);
return $tmp[0];
}
function numPostsSinceDate($first,$last){
$count = $last - $first + 1;
return $count;
}
function cachePosts($first,$last){
$posts = array();
for($i=$first;$i<=$last;$i++){
$thepost = $this->getPostHead($i);
if ($thepost->getDate() != "")
if (!preg_match("/\[[Aa][Nn][Nn][^\]]*\]/",$thepost->getSubject(),$regs))
array_push($posts,$thepost);
}
return $posts;
}
function cacheMessageID($first,$last){
$messages = array();
for($i=$first;$i<=$last;$i++){
$thepost = $this->getPostHead($i);
if ($thepost->getDate() != "")
$messages[$thepost->getMessageID()] = getUnixTimestamp($thepost->getDate(),$thepost->getTime());
}
return $messages;
}
function answeredPosts($cachedposts){
$answer_time = 0;
$unanswered = 0;
$total = count($cachedposts);
for($i=0;$i<$total;$i++){
$post = $cachedposts[$i];
}
return array($answer_time, $unanswered);
}
function getFirstArticleFromDate($first,$last,$date){
$post = new Post(array());
$tmp = new Post(array());
$tmp_first = $first;
# All posts are greater than the passed date
while($tmp->getDate() == "")
$tmp = $this->getPostHead($tmp_first++);
if ($tmp->getDate() >= $date)
return --$tmp_first;
$search = (int) ceil(($first + $last) / 2);
# We've reached the end and no date matches the passed date
if ($search == $last){
$tmp = $this->getPostHead($last); # Make sure the last one is
if ($tmp->getDate() < $date) # not a valid date either
return -1;
}
#print "F: $first L: $last S: $search\n";
while($post->getDate() == "" && $search <= $last){
$post = $this->getPostHead($search);
if ($post->getDate() == ""){
$search++;
}
}
if ($post->getDate() == ""){
return -1; // Error
}
$pdate = $post->getDate();
#print "P: $pdate D: $date\n";
if ($pdate == $date){ # Found an article from the $date
$tmp_search = $search;
while($pdate == $date){ # now get the first one (faster)
$post = $this->getPostHead(--$search);
$pdate = $post->getDate();
if ($pdate == ""){ # Error fetching article
if ($search < $first){
return $tmp_search;
}
}
}
return ++$search;
} else if ($pdate < $date){
return $this->getFirstArticleFromDate($search,$last,$date);
} else if ($pdate > $date){
return $this->getFirstArticleFromDate(($search*2)-$last,$search,$date);
}
}
}
?>