pdo = ($pdo instanceof Settings ? $pdo : new Settings()); $this->tablePerGroup = ($this->pdo->getSetting('tablepergroup') == 0 ? false : true); $nzbSplitLevel = $this->pdo->getSetting('nzbsplitlevel'); $this->nzbSplitLevel = (empty($nzbSplitLevel) ? 1 : $nzbSplitLevel); $this->siteNzbPath = (string)$this->pdo->getSetting('nzbpath'); if (substr($this->siteNzbPath, -1) !== DS) { $this->siteNzbPath .= DS; } } /** * Writes out the nzb when processing releases. Performed outside of smarty due to memory issues * of holding all parts in an array. */ function writeNZBforReleaseId($relid, $name, $catId, $path, $groupID) { $db = new Settings(); $cat = new Category(); $this->groupID = $groupID; // 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'; } $catrow = $cat->getById($catId); $site = new Sites(); $fp = gzopen($path, "w"); if ($fp) { $nzb_guid = ''; gzwrite($fp, "\n"); gzwrite($fp, "\n"); gzwrite($fp, "\n\n"); gzwrite($fp, "\n"); if ($catrow) gzwrite($fp, " " . htmlspecialchars($catrow["title"], ENT_QUOTES, 'utf-8') . "\n"); if ($name != "") gzwrite($fp, " " . htmlspecialchars($name, ENT_QUOTES, 'utf-8') . "\n"); gzwrite($fp, "\n\n"); $result = $db->queryDirect(sprintf("SELECT %s.*, UNIX_TIMESTAMP(date) AS unixdate, groups.name as groupname FROM %s inner join groups on %s.groupid = groups.id WHERE %s.releaseid = %d ORDER BY %s.name", $bName, $bName, $bName, $bName, $relid, $bName)); while ($binrow = $this->pdo->getAssocArray($result)) { $groups = array(); $groupsRaw = explode(' ', $binrow['xref']); foreach ($groupsRaw as $grp) if (preg_match('/^([a-z0-9\.\-_]+):(\d+)?$/i', $grp, $match) && strtolower($grp) !== 'xref') $groups[] = $match[1]; if (count($groups) == 0) $groups[] = $binrow["groupname"]; gzwrite($fp, "\n"); gzwrite($fp, " \n"); foreach ($groups as $group) gzwrite($fp, " " . $group . "\n"); gzwrite($fp, " \n"); gzwrite($fp, " \n"); $resparts = $db->queryDirect(sprintf("SELECT DISTINCT(messageid), size, partnumber FROM %s WHERE binaryid = %d ORDER BY partnumber", $pName, $binrow["id"])); while ($partsrow = $db->getAssocArray($resparts)) { if ($nzb_guid === '') { $nzb_guid = $partsrow['messageid']; } gzwrite($fp, " " . htmlspecialchars($partsrow["messageid"], ENT_QUOTES, 'utf-8') . "\n"); } gzwrite($fp, " \n\n"); } gzwrite($fp, "\n"); gzclose($fp); if (is_file($path)) { $this->pdo->queryExec( sprintf(' UPDATE releases SET nzbstatus = %d %s WHERE id = %d', NZB::NZB_ADDED, ($nzb_guid === '' ? '' : ', nzb_guid = UNHEX( ' . $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"; } } } /** * Builds a full path to the nzb file on disk. nzbs are stored in a subdir of their first char. * * @param $releaseGuid * @param string $sitenzbpath * @param bool $createIfDoesntExist * * @return string */ function getNZBPath($releaseGuid, $sitenzbpath = "", $createIfDoesntExist = false) { if ($sitenzbpath == "") { $sitenzbpath = $this->pdo->getSetting('nzbpath'); } $nzbpath = $sitenzbpath . substr($releaseGuid, 0, 1) . "/"; if ($createIfDoesntExist && !file_exists($nzbpath)) mkdir($nzbpath); return $nzbpath . $releaseGuid . ".nzb.gz"; } /** * 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. * @param array $options * 'no-file-key' => True - use numeric array key; False - Use filename as array key. * 'strip-count' => True - Strip file/part count from file name to make the array key; False - Leave file name as is. * * @return array $result Empty if not an NZB or the contents of the NZB. * * @access public */ public function nzbFileList($nzb, array $options = []) { $defaults = [ 'no-file-key' => true, 'strip-count' => false, ]; $options += $defaults; $num_pars = $i = 0; $result = []; if (!$nzb) { return $result; } $xml = @simplexml_load_string(str_replace("\x0F", '', $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++; } if ($options['no-file-key'] == false) { $i = $title; if ($options['strip-count']) { // Strip file / part count to get proper sorting. $i = preg_replace('#\d+[- ._]?(/|\||[o0]f)[- ._]?\d+?(?![- ._]\d)#i', '', $i); // Change .rar and .par2 to be sorted before .part0x.rar and .volxxx+xxx.par2 if (strpos($i, '.par2') !== false && !preg_match('#\.vol\d+\+\d+\.par2#i', $i)) { $i = str_replace('.par2', '.vol0.par2', $i); } else if (preg_match('#\.rar[^a-z0-9]#i', $i) && !preg_match('#\.part\d+\.rar#i', $i)) { $i = preg_replace('#\.rar(?:[^a-z0-9])#i', '.part0.rar', $i); } } } $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'] = []; } // 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'] = []; } foreach ($file->groups->group as $g) { array_push($result[$i]['groups'], (string)$g); } unset($result[$i]['segments']['@attributes']); if ($options['no-file-key']) { $i++; } } return $result; } }