echo = $echo; $s = new Sites(); $this->c = new ColorCLI(); $this->db = new DB(); $this->site = $s->get(); $t = new Tmux(); $this->tmux = $t->get(); $this->nzbs = (!empty($this->tmux->maxnfoprocessed)) ? $this->tmux->maxnfoprocessed : 100; $this->maxsize = (!empty($this->tmux->maxsizetopostprocess)) ? $this->tmux->maxsizetopostprocess : 100; $this->tmpPath = $this->site->tmpunrarpath; } /** * Look for a TvRage ID in a string. * * @param string $str The string with a TvRage ID. * @return string The TVRage ID on success. * @return bool False on failure. * * @access public */ public function parseRageId($str) { if (preg_match('/tvrage\.com\/shows\/id-(\d{1,6})/i', $str, $matches)) { return trim($matches[1]); } return false; } /** * Confirm this is an NFO file. * * @param string $possibleNFO The nfo. * @param string $guid The guid of the release. * @return bool True on success, False on failure. * * @access public */ public function isNFO($possibleNFO, $guid) { $r = false; if ($possibleNFO === false) { return $r; } // Make sure it's not too big or small, size needs to be at least 12 bytes for header checking. $size = strlen($possibleNFO); if ($size < 100 * 1024 && $size > 12) { // Ignore common file types. if (preg_match( '/(^RIFF|)<\?xml|;\s*Generated\s*by.*SF\w|\A\s*[RP]AR|\A.{0,10}(JFIF|matroska|ftyp|ID3)|\A=newz\[NZB\]=/i' , $possibleNFO)) { return $r; } // file/getid3 work with files, so save to disk $tmpPath = $this->tmpPath.$guid.'.nfo'; file_put_contents($tmpPath, $possibleNFO); // Linux boxes have 'file' (so should Macs) if (strtolower(substr(PHP_OS, 0, 3)) !== 'win') { exec("file -b $tmpPath", $result); if (is_array($result)) { if (count($result) > 1) { $result = implode(',', $result[0]); } else { $result = $result[0]; } } $test = preg_match('#^.*(ISO-8859|UTF-(?:8|16|32) Unicode(?: \(with BOM\)|)|ASCII)(?: English| C++ Program|) text.*$#i', $result); // if the result is false, something went wrong, continue with getID3 tests. if ($test !== false) { if ($test == 1) { @unlink($tmpPath); return true; } // non-printable characters should never appear in text, so rule them out. $test = preg_match('#\x00|\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0B|\x0E|\x0F|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1A|\x1B|\x1C|\x1D|\x1E|\x1F#', $possibleNFO); if ($test) { @unlink($tmpPath); return false; } } } // If on Windows, or above checks couldn't make a categorical identification, // Use getid3 to check if it's an image/video/rar/zip etc.. require_once ("getid3/getid3/getid3.php"); $getid3 = new getid3(); $check = $getid3->analyze($tmpPath); unset($getid3); @unlink($tmpPath); unset($tmpPath); if (isset($check['error'])) { // Check if it's a par2. require_once(WWW_DIR."/lib/rarinfo/par2info.php"); $par2info = new Par2Info(); $par2info->setData($possibleNFO); if ($par2info->error) { // Check if it's an SFV. require_once(WWW_DIR."/lib/rarinfo/sfvinfo.php"); $sfv = new SfvInfo(); $sfv->setData($possibleNFO); if ($sfv->error) { return true; } } } } return $r; } /** * Add an NFO from alternate sources. ex.: PreDB, rar, zip, etc... * * @param object $db Instance of class DB. * @param string $nfo The nfo. * @param array $release The SQL row for this release. * @param object $nntp Instance of class NNTP. * * @return bool True on success, False on failure. * * @access public */ public function addAlternateNfo($db, $nfo, $release, $nntp) { if (!isset($nntp)) { exit($this->c->error("NFO->addAlternateNfo() Not connected to usenet.\n")); } if ($release['ID'] > 0) { if (DB_TYPE === 'mysql') { $compress = 'compress(%s)'; $nc = $db->escapeString($nfo); } else { $compress = '%s'; $nc = $db->escapeString(utf8_encode($nfo)); } $ckreleaseid = $db->queryOneRow(sprintf('SELECT ID FROM releasenfo WHERE releaseID = %d', $release['ID'])); if (!isset($ckreleaseid['ID'])) { $db->queryInsert(sprintf('INSERT INTO releasenfo (nfo, releaseID) VALUES (' . $compress . ', %d)', $nc, $release['ID'])); } $db->exec(sprintf('UPDATE releases SET releasenfoID = 1, nfostatus = 1 WHERE ID = %d', $release['ID'])); if (!isset($release['completion'])) { $release['completion'] = 0; } if ($release['completion'] == 0) { $nzbContents = new NZBContents(array('echo' => $this->echo, 'nntp' => $nntp, 'nfo' => $this, 'db' => $db, 'pp' => new Functions($this->echooutput))); $nzbContents->parseNZB($release['guid'], $release['ID'], $release['groupID']); } return true; } else { return false; } } /** * Attempt to find NFO files inside the NZB's of releases. * * @param string $releaseToWork * @param int $processImdb Attempt to find IMDB id's in the NZB? * @param int $processTvrage Attempt to find TvRage id's in the NZB? * @param string $groupID (optional) The group ID to work on. * @param object $nntp Instance of class NNTP. * * @return int How many NFO's were processed? * * @access public */ public function processNfoFiles($releaseToWork = '', $processImdb = 1, $processTvrage = 1, $groupID = '', $nntp) { if (!isset($nntp)) { exit($this->c->error("Unable to connect to usenet.\n")); } $nfoCount = $ret = 0; $groupID = $groupID === '' ? '' : 'AND groupID = ' . $groupID; $res = array(); if ($releaseToWork === '') { $i = -1; while (($nfoCount != $this->nzbs) && ($i >= -6)) { $res = $this->db->query(sprintf('SELECT ID, guid, groupID, name FROM releases WHERE nfostatus between %d AND -1 AND size < %s ' . $groupID . ' LIMIT %d', $i, $this->maxsize * 1073741824, $this->nzbs)); $nfoCount = count($res); $i--; } } else { $pieces = explode(' =+= ', $releaseToWork); $res = array(array('ID' => $pieces[0], 'guid' => $pieces[1], 'groupID' => $pieces[2], 'name' => $pieces[3])); $nfoCount = 1; } if ($nfoCount > 0) { if ($releaseToWork === '') { $this->c->doEcho($this->c->primary( 'Processing ' . $nfoCount . ' NFO(s), starting at ' . $this->nzbs . ' * = hidden NFO, + = NFO, - = no NFO, f = download failed.' )); // Get count of releases per nfo status $outString = 'Available to process'; for ($i = -1; $i >= -6; $i--) { $ns = $this->db->query('SELECT COUNT(*) AS count FROM releases WHERE nfostatus = ' . $i); $outString .= ', ' . $i . ' = ' . number_format($ns[0]['count']); } $this->c->doEcho($this->c->header($outString . '.')); } $groups = new Groups(); $functions = new Functions(); $nzbContents = new NZBContents(array('echo' => $this->echo, 'nntp' => $nntp, 'nfo' => $this, 'db' => $this->db, 'pp' => new Functions($this->echooutput))); $movie = new Film($this->echo); $tvRage = new TvRage($this->echo); foreach ($res as $arr) { $fetchedBinary = $nzbContents->getNFOfromNZB($arr['guid'], $arr['ID'], $arr['groupID'], $functions->getByNameByID($arr['groupID'])); if ($fetchedBinary !== false) { // Insert nfo into database. $cp = $nc = null; if (DB_TYPE === 'mysql') { $cp = 'COMPRESS(%s)'; $nc = $this->db->escapeString($fetchedBinary); } else if (DB_TYPE === 'pgsql') { $cp = '%s'; $nc = $this->db->escapeString(utf8_encode($fetchedBinary)); } $ckreleaseid = $this->db->queryOneRow(sprintf('SELECT ID FROM releasenfo WHERE releaseID = %d', $arr['ID'])); if (!isset($ckreleaseid['id'])) { $this->db->queryInsert(sprintf('INSERT INTO releasenfo (nfo, releaseID) VALUES (' . $cp . ', %d)', $nc, $arr['ID'])); } $this->db->exec(sprintf('UPDATE releases SET releasenfoID = 1, nfostatus = 1 WHERE ID = %d', $arr['ID'])); $ret++; $movie->doMovieUpdate($fetchedBinary, 'nfo', $arr['ID'], $processImdb); // If set scan for tvrage info. if ($processTvrage == 1) { $rageId = $this->parseRageId($fetchedBinary); if ($rageId !== false) { $show = $tvRage->parseNameEpSeason($arr['name']); if (is_array($show) && $show['name'] != '') { // Update release with season, ep, and air date info (if available) from release title. $tvRage->updateEpInfo($show, $arr['ID']); $rid = $tvRage->getByRageID($rageId); if (!$rid) { $tvrShow = $tvRage->getRageInfoFromService($rageId); $tvRage->updateRageInfo($rageId, $show, $tvrShow, $arr['ID']); } } } } } } } // Remove nfo that we cant fetch after 5 attempts. if ($releaseToWork === '') { $relres = $this->db->query('SELECT ID FROM releases WHERE nfostatus < -6 OR releasenfoID = -1'); foreach ($relres as $relrow) { $this->db->exec(sprintf('DELETE FROM releasenfo WHERE nfo IS NULL and releaseID = %d', $relrow['ID'])); } if ($this->echo) { if ($nfoCount > 0 && $releaseToWork === '') { echo "\n"; } if ($ret > 0 && $releaseToWork === '') { $this->c->doEcho($ret . ' NFO file(s) found/processed.', true); } } } return $ret; } }