| <?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); |
| } |
| } |
| } |
| ?> |