/** * 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) { if ($possibleNFO === false) { return false; } // Make sure it's not too big or small, size needs to be at least 12 bytes for header checking. Ignore common file types. $size = strlen($possibleNFO); if ($size < 65535 && $size > 11 && !preg_match('/\\A(\\s*<\\?xml|=newz\\[NZB\\]=|RIFF|\\s*[RP]AR|.{0,10}(JFIF|matroska|ftyp|ID3))|;\\s*Generated\\s*by.*SF\\w/i', $possibleNFO)) { // File/GetId3 work with files, so save to disk. $tmpPath = $this->tmpPath . $guid . '.nfo'; file_put_contents($tmpPath, $possibleNFO); $result = Misc::fileInfo($tmpPath); if (!empty($result)) { // Check if it's text. if (preg_match('/(ASCII|ISO-8859|UTF-(8|16|32).*?)\\s*text/', $result)) { @unlink($tmpPath); return true; // Or binary. } else { if (preg_match('/^(JPE?G|Parity|PNG|RAR|XML|(7-)?[Zz]ip)/', $result) || preg_match('/[\\x00-\\x08\\x12-\\x1F\\x0B\\x0E\\x0F]/', $possibleNFO)) { @unlink($tmpPath); return false; } } } // If above checks couldn't make a categorical identification, Use GetId3 to check if it's an image/video/rar/zip etc.. $check = (new \getid3())->analyze($tmpPath); @unlink($tmpPath); if (isset($check['error'])) { // Check if it's a par2. $par2info = new \Par2Info(); $par2info->setData($possibleNFO); if ($par2info->error) { // Check if it's an SFV. $sfv = new \SfvInfo(); $sfv->setData($possibleNFO); if ($sfv->error) { return true; } } } } return false; }
/** * Get file info from inside PAR2, store it in DB, attempt to get a release name. * * @param string $fileLocation */ protected function _siftPAR2Info($fileLocation) { $this->_par2Info->open($fileLocation); if ($this->_par2Info->error) { return; } $releaseInfo = $this->pdo->queryOneRow(sprintf(' SELECT UNIX_TIMESTAMP(postdate) AS postdate, proc_pp FROM releases WHERE id = %d', $this->_release['id'])); if ($releaseInfo === false) { return; } // Only get a new name if the category is OTHER. $foundName = true; if (nZEDb_RENAME_PAR2 && $releaseInfo['proc_pp'] == 0 && in_array((int) $this->_release['categoryid'], [Category::CAT_BOOKS_OTHER, Category::CAT_GAME_OTHER, Category::CAT_MOVIE_OTHER, Category::CAT_MUSIC_OTHER, Category::CAT_PC_PHONE_OTHER, Category::CAT_TV_OTHER, Category::CAT_OTHER_HASHED, Category::CAT_XXX_OTHER, Category::CAT_MISC])) { $foundName = false; } $filesAdded = 0; $files = $this->_par2Info->getFileList(); foreach ($files as $file) { if (!isset($file['name'])) { continue; } // If we found a name and added 10 files, stop. if ($foundName === true && $filesAdded > 10) { break; } // Add to release files. if ($this->_addPAR2Files) { if ($filesAdded < 11 && $this->pdo->queryOneRow(sprintf('SELECT id FROM release_files WHERE releaseid = %d AND name = %s', $this->_release['id'], $this->pdo->escapeString($file['name']))) === false) { // Try to add the files to the DB. if ($this->_releaseFiles->add($this->_release['id'], $file['name'], $file['size'], $releaseInfo['postdate'], 0)) { $filesAdded++; } } } else { $filesAdded++; } // Try to get a new name. if ($foundName === false) { $this->_release['textstring'] = $file['name']; $this->_release['releaseid'] = $this->_release['id']; if ($this->_nameFixer->checkName($this->_release, $this->_echoCLI ? true : false, 'PAR2, ', 1, 1) === true) { $foundName = true; } } } // Update the file count with the new file count + old file count. $this->pdo->queryExec(sprintf('UPDATE releases SET rarinnerfilecount = rarinnerfilecount + %d WHERE id = %d', $filesAdded, $this->_release['id'])); $this->_foundPAR2Info = true; }
/** * Attempt to get a better name from a par2 file and categorize the release. * * @note Called from NZBContents.php * * @param string $messageID MessageID from NZB file. * @param int $relID id of the release. * @param int $groupID Group id of the release. * @param \NNTP $nntp Class NNTP * @param int $show Only show result or apply iy. * * @return bool */ public function parsePAR2($messageID, $relID, $groupID, &$nntp, $show) { if ($messageID === '') { return false; } $query = $this->pdo->queryOneRow(sprintf(' SELECT id, groupid, categoryid, name, searchname, UNIX_TIMESTAMP(postdate) AS post_date, id AS releaseid FROM releases WHERE isrenamed = 0 AND id = %d', $relID)); if ($query === false) { return false; } // Only get a new name if the category is OTHER. $foundName = true; if (!in_array((int) $query['categoryid'], array(\Category::CAT_BOOK_OTHER, \Category::CAT_GAME_OTHER, \Category::CAT_MOVIE_OTHER, \Category::CAT_MUSIC_OTHER, \Category::CAT_PC_MOBILEOTHER, \Category::CAT_TV_OTHER, \Category::CAT_MISC_HASHED, \Category::CAT_XXX_OTHER, \Category::CAT_MISC_OTHER))) { $foundName = false; } // Get the PAR2 file. $par2 = $nntp->getMessages($this->groups->getByNameByID($groupID), $messageID, $this->alternateNNTP); if ($nntp->isError($par2)) { return false; } // Put the PAR2 into Par2Info, check if there's an error. $this->_par2Info->setData($par2); if ($this->_par2Info->error) { return false; } // Get the file list from Par2Info. $files = $this->_par2Info->getFileList(); if ($files !== false && count($files) > 0) { $filesAdded = 0; // Loop through the files. foreach ($files as $file) { if (!isset($file['name'])) { continue; } // If we found a name and added 10 files, stop. if ($foundName === true && $filesAdded > 10) { break; } if ($this->addpar2) { // Add to release files. if ($filesAdded < 11 && $this->pdo->queryOneRow(sprintf(' SELECT id FROM releasefiles WHERE releaseid = %d AND name = %s', $relID, $this->pdo->escapeString($file['name']))) === false) { // Try to add the files to the DB. if ($this->releaseFiles->add($relID, $file['name'], $file['size'], $query['post_date'], 0)) { $filesAdded++; } } } else { $filesAdded++; } // Try to get a new name. if ($foundName === false) { $query['textstring'] = $file['name']; if ($this->nameFixer->checkName($query, 1, 'PAR2, ', 1, $show) === true) { $foundName = true; } } } // If we found some files. if ($filesAdded > 0) { $this->debugging->log(get_class(), __FUNCTION__, 'Added ' . $filesAdded . ' releasefiles from PAR2 for ' . $query['searchname'], \Logger::LOG_INFO); // Update the file count with the new file count + old file count. $this->pdo->queryExec(sprintf(' UPDATE releases SET rarinnerfilecount = rarinnerfilecount + %d WHERE id = %d', $filesAdded, $relID)); } if ($foundName === true) { return true; } } 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) { if ($possibleNFO === false) { return false; } // Make sure it's not too big or small, size needs to be at least 12 bytes for header checking. Ignore common file types. $size = strlen($possibleNFO); if ($size < 65535 && $size > 11 && !preg_match('/\\A(\\s*<\\?xml|=newz\\[NZB\\]=|RIFF|\\s*[RP]AR|.{0,10}(JFIF|matroska|ftyp|ID3))|;\\s*Generated\\s*by.*SF\\w/i', $possibleNFO)) { // 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), Windows *can* have it too: see GNUWIN.txt in docs. if (nzedb\utility\Utility::hasCommand('file')) { exec('file -b "' . $tmpPath . '"', $result); if (is_array($result)) { if (count($result) > 1) { $result = implode(',', $result[0]); } else { $result = $result[0]; } } // Check if it's text. if (preg_match('/(ASCII|ISO-8859|UTF-(8|16|32).*?)\\s*text/', $result)) { @unlink($tmpPath); return true; // Or binary. } else { if (preg_match('/^(JPE?G|Parity|PNG|RAR|XML|(7-)?[Zz]ip)/', $result) || preg_match('/[\\x00-\\x08\\x12-\\x1F\\x0B\\x0E\\x0F]/', $possibleNFO)) { @unlink($tmpPath); return false; } } } // If above checks couldn't make a categorical identification, Use GetId3 to check if it's an image/video/rar/zip etc.. $getid3 = new getid3(); $check = $getid3->analyze($tmpPath); @unlink($tmpPath); if (isset($check['error'])) { // Check if it's a par2. $par2info = new Par2Info(); $par2info->setData($possibleNFO); if ($par2info->error) { // Check if it's an SFV. $sfv = new SfvInfo(); $sfv->setData($possibleNFO); if ($sfv->error) { return true; } } } } return false; }