pdo = ($pdo instanceof \DB ? $pdo : new \DB()); $s = new Sites(); $this->site = $s->get(); $this->tablePerGroup = ($this->site->tablepergroup == 0 ? false : true); $nzbSplitLevel = $this->site->nzbsplitlevel; $this->nzbSplitLevel = (empty($nzbSplitLevel) ? 1 : $nzbSplitLevel); $this->siteNzbPath = (string)$this->site->nzbpath; if (substr($this->siteNzbPath, -1) !== DS) { $this->siteNzbPath .= DS; } } /** * Initiate class vars when writing NZB's. * * @param int $groupID * * @access public */ public function initiateForWrite($groupID) { $this->groupID = $groupID; $site = new Sites(); // Set table names if ($this->tablePerGroup === true) { if ($this->groupID == '') { exit("$this->groupID is missing\n"); } $bName = 'binaries_' . $this->groupID; $pName = 'parts_' . $this->groupID; } else { $bName = 'binaries'; $pName = 'parts'; } $this->_binariesQuery = sprintf( 'SELECT %s.*, UNIX_TIMESTAMP(%s.date) AS udate, groups.name AS groupname FROM %s INNER JOIN groups ON %s.groupID = groups.ID WHERE %s.releaseID = ', $bName, $bName, $bName, $bName, $bName ); $this->_partsQuery = ( 'SELECT DISTINCT(messageID), size, partnumber FROM ' . $pName . ' WHERE binaryID = %d ORDER BY partnumber' ); $this->_nzbHeadString = ( "\n\n\n\n\n %s\n %s\n\n\n" ); } /** * Write an NZB to the hard drive for a single release. * * @param int $relID The ID of the release in the DB. * @param string $relGuid The guid of the release. * @param string $name The name of the release. * @param string $cTitle The name of the category this release is in. * * @return bool Have we successfully written the NZB to the hard drive? * * @access public */ public function writeNZBforReleaseId($relID, $relGuid, $name, $cTitle) { $path = ($this->buildNZBPath($relGuid, $this->nzbSplitLevel, true) . $relGuid . '.nzb.gz'); $fp = gzopen($path, 'wb7'); if ($fp) { $nzb_guid = ''; gzwrite( $fp, sprintf( $this->_nzbHeadString, htmlspecialchars($cTitle, ENT_QUOTES, 'utf-8'), htmlspecialchars($name, ENT_QUOTES, 'utf-8') ) ); $binaries = $this->pdo->queryDirect($this->_binariesQuery. $relID . ' ORDER BY name'); if ($binaries instanceof \Traversable) { foreach ($binaries as $binary) { $poster = htmlspecialchars($binary['fromname'], ENT_QUOTES, 'utf-8'); if ($binary instanceof \Traversable) { foreach ($binary as $bin) { // Buffer segment writes, increases performance. $string = ''; $parts = $this->pdo->queryDirect(sprintf($this->_partsQuery, $bin['ID'])); if ($parts instanceof \Traversable) { foreach ($parts as $part) { if ($nzb_guid === '') { $nzb_guid = $part['messageID']; } $string .= ( ' ' . htmlspecialchars($part['messageID'], ENT_QUOTES, 'utf-8') . "\n" ); } } gzwrite($fp, '\n \n " . $bin['groupname'] . "\n \n \n" . $string . " \n\n" ); } } } } gzwrite($fp, ''); gzclose($fp); if (is_file($path)) { $this->pdo->queryExec( sprintf(' UPDATE releases SET nzbstatus = %d %s WHERE ID = %d', \Enzebe::NZB_ADDED, ($nzb_guid === '' ? '' : ', nzb_guid = ' . $this->pdo->escapestring(md5($nzb_guid))), $relID ) ); // Chmod to fix issues some users have with file permissions. chmod($path, 0777); return true; } else { echo "ERROR: $path does not exist.\n"; } } return false; } /** * Build a folder path on the hard drive where the NZB file will be stored. * * @param string $releaseGuid The guid of the release. * @param int $levelsToSplit How many sub-paths the folder will be in. * @param bool $createIfNotExist Create the folder if it doesn't exist. * * @return string $nzbpath The path to store the NZB file. * * @access public */ private function buildNZBPath($releaseGuid, $levelsToSplit, $createIfNotExist) { $nzbPath = ''; for ($i = 0; $i < $levelsToSplit && $i < 32; $i++) { $nzbPath .= substr($releaseGuid, $i, 1) . DS; } $nzbPath = $this->siteNzbPath . $nzbPath; if ($createIfNotExist === true && !is_dir($nzbPath)) { mkdir($nzbPath, 0777, true); } return $nzbPath; } /** * Retrieve path + filename of the NZB to be stored. * * @param string $releaseGuid The guid of the release. * @param int $levelsToSplit How many sub-paths the folder will be in. (optional) * @param bool $createIfNotExist Create the folder if it doesn't exist. (optional) * * @return string Path+filename. * * @access public */ public function getNZBPath($releaseGuid, $levelsToSplit = 0, $createIfNotExist = false) { if ($levelsToSplit === 0) { $levelsToSplit = $this->nzbSplitLevel; } return ($this->buildNZBPath($releaseGuid, $levelsToSplit, $createIfNotExist) . $releaseGuid . '.nzb.gz'); } /** * Determine is an NZB exists, returning the path+filename, if not return false. * * @param string $releaseGuid The guid of the release. * * @return bool|string On success: (string) Path+file name of the nzb. * On failure: (bool) False. * * @access public */ public function NZBPath($releaseGuid) { $nzbFile = $this->getNZBPath($releaseGuid); return (is_file($nzbFile) ? $nzbFile : false); } /** * Retrieve various information on a NZB file (the subject, # of pars, * file extensions, file sizes, file completion, group names, # of parts). * * @param string $nzb The NZB contents in a string. * * @return array $result Empty if not an NZB or the contents of the NZB. * * @access public */ public function nzbFileList($nzb) { $num_pars = $i = 0; $result = array(); if (!$nzb) { return $result; } $nzb = str_replace("\x0F", '', $nzb); $xml = @simplexml_load_string($nzb); if (!$xml || strtolower($xml->getName()) !== 'nzb') { return $result; } foreach ($xml->file as $file) { // Subject. $title = (string)$file->attributes()->subject; // Amount of pars. if (stripos($title, '.par2')) { $num_pars++; } $result[$i]['title'] = $title; // Extensions. if (preg_match( '/\.(\d{2,3}|7z|ace|ai7|srr|srt|sub|aiff|asc|avi|audio|bin|bz2|' . 'c|cfc|cfm|chm|class|conf|cpp|cs|css|csv|cue|deb|divx|doc|dot|' . 'eml|enc|exe|file|gif|gz|hlp|htm|html|image|iso|jar|java|jpeg|' . 'jpg|js|lua|m|m3u|mkv|mm|mov|mp3|mp4|mpg|nfo|nzb|odc|odf|odg|odi|odp|' . 'ods|odt|ogg|par2|parity|pdf|pgp|php|pl|png|ppt|ps|py|r\d{2,3}|' . 'ram|rar|rb|rm|rpm|rtf|sfv|sig|sql|srs|swf|sxc|sxd|sxi|sxw|tar|' . 'tex|tgz|txt|vcf|video|vsd|wav|wma|wmv|xls|xml|xpi|xvid|zip7|zip)' . '[" ](?!(\)|\-))/i', $title, $ext ) ) { if (preg_match('/\.r\d{2,3}/i', $ext[0])) { $ext[1] = 'rar'; } $result[$i]['ext'] = strtolower($ext[1]); } else { $result[$i]['ext'] = ''; } $fileSize = $numSegments = 0; // Parts. if (!isset($result[$i]['segments'])) { $result[$i]['segments'] = array(); } // File size. foreach ($file->segments->segment as $segment) { array_push($result[$i]['segments'], (string) $segment); $fileSize += $segment->attributes()->bytes; $numSegments++; } $result[$i]['size'] = $fileSize; // File completion. if (preg_match('/(\d+)\)$/', $title, $parts)) { $result[$i]['partstotal'] = $parts[1]; } $result[$i]['partsactual'] = $numSegments; // Groups. if (!isset($result[$i]['groups'])) { $result[$i]['groups'] = array(); } foreach ($file->groups->group as $g) { array_push($result[$i]['groups'], (string) $g); } unset($result[$i]['segments']['@attributes']); $i++; } return $result; } }