/** * 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; }
/** * Go through all the extracted files in the temp folder and process them. */ protected function _processExtractedFiles() { $nestedLevels = 0; // Go through all the files in the temp folder, look for compressed files, extract them and the nested ones. while ($nestedLevels < $this->_maxNestedLevels) { // Break out if we checked more than x compressed files. if ($this->_compressedFilesChecked >= self::maxCompressedFilesToCheck) { break; } $foundCompressedFile = false; // Get all the compressed files in the temp folder. $files = $this->_getTempDirectoryContents('/.*\\.([rz]\\d{2,}|rar|zipx?|0{0,2}1)($|[^a-z0-9])/i'); if ($files instanceof \Traversable) { foreach ($files as $file) { // Check if the file exists. if (is_file($file[0])) { $rarData = @file_get_contents($file[0]); if ($rarData !== false) { $this->_processCompressedData($rarData); $foundCompressedFile = true; } @unlink($file[0]); } } } // If we found no compressed files, break out. if ($foundCompressedFile === false) { break; } $nestedLevels++; } $fileType = []; // Get all the remaining files in the temp dir. $files = $this->_getTempDirectoryContents(); if ($files instanceof \Traversable) { foreach ($files as $file) { $file = (string) $file; // Skip /. and /.. if (preg_match('/[\\/\\\\]\\.{1,2}$/', $file)) { continue; } if (is_file($file)) { // Process PAR2 files. if ($this->_foundPAR2Info === false && preg_match('/\\.par2$/', $file)) { $this->_siftPAR2Info($file); } else { if ($this->_releaseHasNoNFO === true && preg_match('/(\\.(nfo|inf|ofn)|info\\.txt)$/i', $file)) { $this->_processNfoFile($file); } else { if (($this->_foundAudioInfo === false || $this->_foundAudioSample === false) && preg_match('/(.*)' . $this->_audioFileRegex . '$/i', $file, $fileType)) { // Try to get audio sample/audio media info. @rename($file, $this->tmpPath . 'audiofile.' . $fileType[2]); $this->_getAudioInfo($this->tmpPath . 'audiofile.' . $fileType[2], $fileType[2]); @unlink($this->tmpPath . 'audiofile.' . $fileType[2]); } else { if ($this->_foundJPGSample === false && preg_match('/\\.jpe?g$/i', $file)) { $this->_getJPGSample($file); @unlink($file); } else { if (($this->_foundSample === false || $this->_foundVideo === false || $this->_foundMediaInfo === false) && preg_match('/(.*)' . $this->_videoFileRegex . '$/i', $file)) { $this->_processVideoFile($file); } else { if (in_array($this->_releaseGroupName, ['alt.binaries.u4e', 'alt.binaries.mom']) && preg_match('/Linux_2rename\\.sh/i', $file) && ($this->_release['categoryid'] == Category::CAT_OTHER_HASHED || $this->_release['categoryid'] == Category::CAT_MISC)) { $this->_processU4ETitle($file); } else { $output = Misc::fileInfo($file); if (!empty($output)) { switch (true) { case $this->_foundJPGSample === false && preg_match('/^JPE?G/i', $output): $this->_getJPGSample($file); @unlink($file); break; case ($this->_foundMediaInfo === false || $this->_foundSample === false || $this->_foundVideo === false) && preg_match('/Matroska data|MPEG v4|MPEG sequence, v2|\\WAVI\\W/i', $output): $this->_processVideoFile($file); break; case ($this->_foundAudioSample === false || $this->_foundAudioInfo === false) && preg_match('/^FLAC|layer III|Vorbis audio/i', $output, $fileType): switch ($fileType[0]) { case 'FLAC': $fileType = 'FLAC'; break; case 'layer III': $fileType = 'MP3'; break; case 'Vorbis audio': $fileType = 'OGG'; break; } @rename($file, $this->tmpPath . 'audiofile.' . $fileType); $this->_getAudioInfo($this->tmpPath . 'audiofile.' . $fileType, $fileType); @unlink($this->tmpPath . 'audiofile.' . $fileType); break; case $this->_foundPAR2Info === false && preg_match('/^Parity/i', $output): $this->_siftPAR2Info($file); break; } } } } } } } } } } } }