/** * Get video info from a Site ID and column. * * @param string $siteColumn * @param integer $siteID * * @return array|false False if invalid site, or ID not found; video.id value otherwise. */ protected function getVideoIDFromSiteID($siteColumn, $siteID) { if (in_array($siteColumn, $this->sites)) { $result = $this->pdo->queryOneRow("SELECT id FROM videos WHERE {$siteColumn} = {$siteID}"); return isset($result['id']) ? $result['id'] : false; } return false; }
/** * @param $relid * @param $uid */ public function postComment($relid, $uid) { $text = 'This release has failed to download properly. It might fail for other users too. This comment is automatically generated.'; $dbl = $this->pdo->queryOneRow(sprintf('SELECT text FROM release_comments WHERE releaseid = %d AND userid = %d', $relid, $uid)); if ($dbl['text'] != $text) { $this->rc->addComment($relid, $text, $uid, ''); } }
/** * Collect and return various capability information for usage in API * * @return array */ public function getForMenu() { $serverroot = ''; $https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? true : false; if (isset($_SERVER['SERVER_NAME'])) { $serverroot = ($https === true ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT'] != '80' && $_SERVER['SERVER_PORT'] != '443' ? ':' . $_SERVER['SERVER_PORT'] : '') . WWW_TOP . '/'; } return ['server' => ['appversion' => (new Versions())->getTagVersion(), 'version' => '0.1', 'title' => $this->pdo->getSetting('title'), 'strapline' => $this->pdo->getSetting('strapline'), 'email' => $this->pdo->getSetting('email'), 'url' => $serverroot, 'image' => $serverroot . 'themes/shared/images/logo.png'], 'limits' => ['max' => 100, 'default' => 100], 'registration' => ['available' => 'yes', 'open' => $this->pdo->getSetting('registerstatus') == 0 ? 'yes' : 'no'], 'searching' => ['search' => ['available' => 'yes', 'supportedParams' => 'q'], 'tv-search' => ['available' => 'yes', 'supportedParams' => 'q,vid,tvdbid,traktid,rid,tvmazeid,imdbid,tmdbid,season,ep'], 'movie-search' => ['available' => 'yes', 'supportedParams' => 'q,imdbid'], 'audio-search' => ['available' => 'no', 'supportedParams' => '']]]; }
/** * @param array $options Class instances / Echo to cli. */ public function __construct(array $options = array()) { $defaults = ['Echo' => false, 'Settings' => null]; $options += $defaults; $this->echooutput = $options['Echo'] && nZEDb_ECHOCLI; $this->pdo = $options['Settings'] instanceof Settings ? $options['Settings'] : new Settings(); $qty = $this->pdo->getSetting('maxanidbprocessed'); $this->aniqty = !empty($qty) ? $qty : 100; $this->imgSavePath = nZEDb_COVERS . 'anime' . DS; }
/** * Update Sphinx Relases index for given releaseid. * * @param int $releaseID * @param \nzedb\db\Settings $pdo */ public function updateRelease($releaseID, Settings $pdo) { if (!is_null($this->sphinxQL)) { $new = $pdo->queryOneRow(sprintf(' SELECT r.id, r.name, r.searchname, r.fromname, IFNULL(GROUP_CONCAT(rf.name SEPARATOR " "),"") filename FROM releases r LEFT JOIN release_files rf ON (r.id=rf.releaseid) WHERE r.id = %d GROUP BY r.id LIMIT 1', $releaseID)); if ($new !== false) { $this->insertRelease($new); } } }
/** * Delete release from Sphinx RT table. * @param array $identifiers ['g' => Release GUID(mandatory), 'id => ReleaseID(optional, pass false)] * @param \nzedb\db\Settings $pdo */ public function deleteRelease($identifiers, Settings $pdo) { if (!is_null($this->sphinxQL)) { if ($identifiers['i'] === false) { $identifiers['i'] = $pdo->queryOneRow(sprintf('SELECT id FROM releases WHERE guid = %s', $pdo->escapeString($identifiers['g']))); if ($identifiers['i'] !== false) { $identifiers['i'] = $identifiers['i']['id']; } } if ($identifiers['i'] !== false) { $this->sphinxQL->queryExec(sprintf('DELETE FROM releases_rt WHERE id = %s', $identifiers['i'])); } } }
public function startRunning() { if (!$this->isRunning()) { return $this->pdo->queryExec("UPDATE tmux SET value = '1' WHERE setting = 'running'"); } return true; }
/** * If a collection has been stuck for $this->collectionTimeout hours, delete it, it's bad. * * @param array $group * @param string $where * * @void * @access private */ private function processStuckCollections(array $group, $where) { $obj = $this->pdo->queryExec(sprintf("\n\t\t\t\tDELETE c, b, p FROM %s c\n\t\t\t\tLEFT JOIN %s b ON (c.id=b.collection_id)\n\t\t\t\tLEFT JOIN %s p ON (b.id=p.binaryid)\n\t\t\t\tWHERE\n\t\t\t\t\tc.added <\n\t\t\t\t\tDATE_SUB((SELECT value FROM settings WHERE setting = 'last_run_time'), INTERVAL %d HOUR)\n\t\t\t\t%s", $group['cname'], $group['bname'], $group['pname'], $this->collectionTimeout, $where)); if ($this->echoCLI && is_object($obj) && $obj->rowCount()) { $this->pdo->log->doEcho($this->pdo->log->primary('Deleted ' . $obj->rowCount() . ' broken/stuck collections.')); } }
/** * Fetch a comment and insert it. * * @param string $messageID Message-ID for the article. * @param string $siteID ID of the site. * * @return bool * * @access protected */ protected function insertNewComment(&$messageID, &$siteID) { // Get the article body. $body = $this->nntp->getMessages(self::group, $messageID); // Check if there's an error. if ($this->nntp->isError($body)) { return false; } // Decompress the body. $body = @gzinflate($body); if ($body === false) { return false; } // JSON Decode the body. $body = json_decode($body, true); if ($body === false) { return false; } // Just in case. if (!isset($body['USER']) || !isset($body['SID']) || !isset($body['RID']) || !isset($body['TIME']) | !isset($body['BODY'])) { return false; } // Insert the comment. if ($this->pdo->queryExec(sprintf(' INSERT INTO release_comments (text, createddate, shareid, nzb_guid, siteid, username, user_id, releaseid, shared, host) VALUES (%s, %s, %s, UNHEX(%s), %s, %s, 0, 0, 2, "")', $this->pdo->escapeString($body['BODY']), $this->pdo->from_unixtime($body['TIME'] > time() ? time() : $body['TIME']), $this->pdo->escapeString($body['SID']), $this->pdo->escapeString($body['RID']), $this->pdo->escapeString($siteID), $this->pdo->escapeString(substr($body['USER'], 0, 3) === 'sn-' ? 'SH_ANON' : 'SH_' . $body['USER'])))) { return true; } return false; }
/** * Inserts Genre and returns last affected row (Genre ID) * * @param $genre * * @return bool */ private function insertGenre($genre) { if (isset($genre)) { $res = $this->pdo->queryInsert(sprintf("INSERT INTO genres (title, type, disabled) VALUES (%s ,%d ,%d)", $this->pdo->escapeString($genre), 6000, 0)); return $res; } }
public function addFull($id, $xml) { $ckid = $this->pdo->queryOneRow(sprintf('SELECT releaseid FROM releaseextrafull WHERE releaseid = %s', $id)); if (!isset($ckid['releaseid'])) { return $this->pdo->queryExec(sprintf('INSERT INTO releaseextrafull (releaseid, mediainfo) VALUES (%d, %s)', $id, $this->pdo->escapeString($xml))); } }
public function processGamesReleases() { $res = $this->pdo->queryDirect(sprintf(' SELECT searchname, id FROM releases WHERE nzbstatus = 1 %s AND gamesinfo_id = 0 AND categoryid = 4050 ORDER BY postdate DESC LIMIT %d', $this->renamed, $this->gameQty)); if ($res instanceof \Traversable && $res->rowCount() > 0) { if ($this->echoOutput) { $this->pdo->log->doEcho($this->pdo->log->header("Processing " . $res->rowCount() . ' games release(s).')); } foreach ($res as $arr) { // Reset maxhitrequest $this->maxHitRequest = false; $startTime = microtime(true); $usedgb = false; $gameInfo = $this->parseTitle($arr['searchname']); if ($gameInfo !== false) { if ($this->echoOutput) { $this->pdo->log->doEcho($this->pdo->log->headerOver('Looking up: ') . $this->pdo->log->primary($gameInfo['title'] . ' (PC)')); } // Check for existing games entry. $gameCheck = $this->getGamesInfoByName($gameInfo['title']); if ($gameCheck === false) { $gameId = $this->updateGamesInfo($gameInfo); $usedgb = true; if ($gameId === false) { $gameId = -2; // Leave gamesinfo_id 0 to parse again if ($this->maxHitRequest === true) { $gameId = 0; } } } else { $gameId = $gameCheck['id']; } // Update release. $this->pdo->queryExec(sprintf('UPDATE releases SET gamesinfo_id = %d WHERE id = %d', $gameId, $arr['id'])); } else { // Could not parse release title. $this->pdo->queryExec(sprintf('UPDATE releases SET gamesinfo_id = %d WHERE id = %d', -2, $arr['id'])); if ($this->echoOutput) { echo '.'; } } // Sleep to not flood giantbomb. $diff = floor((microtime(true) - $startTime) * 1000000); if ($this->sleepTime * 1000 - $diff > 0 && $usedgb === true) { usleep($this->sleepTime * 1000 - $diff); } } } else { if ($this->echoOutput) { $this->pdo->log->doEcho($this->pdo->log->header('No games releases to process.')); } } }
protected function setUserPreferences() { $this->userdata = $this->users->getById($this->users->currentUserId()); $this->userdata['categoryexclusions'] = $this->users->getCategoryExclusion($this->users->currentUserId()); // Change to the user's selected theme, if they selected one, else use the admin set one. $this->theme = isset($this->userdata['style']) ? $this->userdata['style'] : 'None'; if ($this->theme == 'None') { $this->theme = $this->settings->getSetting('site.main.style'); } if (lcfirst($this->theme) === $this->theme) { // TODO add redirect to error page telling the user their theme name is invalid (after SQL patch to update current users is added). $this->theme = ucfirst($this->theme); } // Update last login every 15 mins. if (strtotime($this->userdata['now']) - 900 > strtotime($this->userdata['lastlogin'])) { $this->users->updateSiteAccessed($this->userdata['id']); } $this->smarty->assign('userdata', $this->userdata); $this->smarty->assign('loggedin', 'true'); $sab = new SABnzbd($this); $this->smarty->assign('sabintegrated', $sab->integratedBool); if ($sab->integratedBool !== false && $sab->url != '' && $sab->apikey != '') { $this->smarty->assign('sabapikeytype', $sab->apikeytype); } switch ((int) $this->userdata['role']) { case Users::ROLE_ADMIN: $this->smarty->assign('isadmin', 'true'); break; case Users::ROLE_MODERATOR: $this->smarty->assign('ismod', 'true'); } }
/** * @param bool $activeOnly * * @return array */ public function getGenres($activeOnly = false) { if ($activeOnly) { return $this->pdo->query("SELECT musicgenre.* FROM musicgenre INNER JOIN (SELECT DISTINCT musicgenreid FROM musicinfo) x ON x.musicgenreid = musicgenre.id ORDER BY title"); } else { return $this->pdo->query("SELECT * FROM musicgenre ORDER BY title"); } }
/** * @param bool $activeOnly * * @return array */ public function getGenres($activeOnly = false) { if ($activeOnly) { return $this->pdo->query("\n\t\t\t\tSELECT ge.*\n\t\t\t\tFROM genres ge\n\t\t\t\tINNER JOIN\n\t\t\t\t(\n\t\t\t\t\tSELECT DISTINCT genre_id\n\t\t\t\t\tFROM musicinfo\n\t\t\t\t) x ON x.genre_id = ge.id\n\t\t\t\tWHERE ge.type = 3000\n\t\t\t\tORDER BY title"); } else { return $this->pdo->query("\n\t\t\t\tSELECT * FROM genres\n\t\t\t\tWHERE type = 3000\n\t\t\t\tORDER BY title"); } }
/** * No request ID was found, update the release. * * @param int $releaseID * @param int $status */ protected function _requestIdNotFound($releaseID, $status) { if ($releaseID == 0) { return; } $this->pdo->queryExec(sprintf(' UPDATE releases SET reqidstatus = %d WHERE id = %d', $status, $releaseID)); }
/** * Retrieves all info for a specific AniDB ID * * @param int $anidbID * @return array|boolean */ public function getAnimeInfo($anidbID) { $animeInfo = $this->pdo->query(sprintf('SELECT at.anidbid, at.lang, at.title, ai.startdate, ai.enddate, ai.updated, ai.related, ai.creators, ai.description, ai.rating, ai.picture, ai.categories, ai.characters, ai.type, ai.similar FROM anidb_titles AS at LEFT JOIN anidb_info ai USING (anidbid) WHERE at.anidbid = %d', $anidbID)); return isset($animeInfo[0]) ? $animeInfo[0] : false; }
/** This function updates a single variable column in releases * The first parameter is the column to update, the second is the value * The final parameter is the ID of the release to update * * @param string $column * @param integer $status * @param integer $id */ private function _updateSingleColumn($column = '', $status = 0, $id = 0) { if ($column !== '' && $id !== 0) { $this->pdo->queryExec(sprintf(' UPDATE releases SET %s = %s WHERE id = %d', $column, is_numeric($status) ? $status : $this->pdo->escapeString($status), $id)); } }
public function getCommentsForUserRange($uid, $start, $num) { if ($start === false) { $limit = ''; } else { $limit = " LIMIT {$num} OFFSET {$start}"; } return $this->pdo->query(sprintf("\n\t\t\t\tSELECT release_comments.*\n\t\t\t\tFROM release_comments\n\t\t\t\tWHERE user_id = %d\n\t\t\t\tORDER BY release_comments.createddate DESC %s", $uid, $limit)); }
public function data_getForMenuByTypeAndRole($id, $role) { if ($role == Users::ROLE_ADMIN) { $role = ""; } else { $role = sprintf("AND (role = %d OR role = 0)", $role); } return $this->pdo->query(sprintf("SELECT * FROM content WHERE showinmenu = 1 AND status = 1 AND contenttype = %d %s ", $id, $role)); }
public function processConsoleReleases() { $res = $this->pdo->queryDirect(sprintf(' SELECT searchname, id FROM releases WHERE nzbstatus = %d %s AND consoleinfoid IS NULL AND categoryid BETWEEN 1000 AND 1999 ORDER BY postdate DESC LIMIT %d', NZB::NZB_ADDED, $this->renamed, $this->gameqty)); if ($res instanceof Traversable && $res->rowCount() > 0) { if ($this->echooutput) { $this->pdo->log->doEcho($this->pdo->log->header("Processing " . $res->rowCount() . ' console release(s).')); } foreach ($res as $arr) { $startTime = microtime(true); $usedAmazon = false; $gameId = self::CONS_NTFND; $gameInfo = $this->parseTitle($arr['searchname']); if ($gameInfo !== false) { if ($this->echooutput) { $this->pdo->log->doEcho($this->pdo->log->headerOver('Looking up: ') . $this->pdo->log->primary($gameInfo['title'] . ' (' . $gameInfo['platform'] . ')')); } // Check for existing console entry. $gameCheck = $this->getConsoleInfoByName($gameInfo['title'], $gameInfo['platform']); if ($gameCheck === false) { $gameId = $this->updateConsoleInfo($gameInfo); $usedAmazon = true; } else { if ($this->echooutput) { $this->pdo->log->doEcho($this->pdo->log->headerOver("Found Local: ") . $this->pdo->log->primary("{$gameCheck['title']} - {$gameCheck['platform']}") . PHP_EOL); } $gameId = $gameCheck['id']; } } elseif ($this->echooutput) { echo '.'; } // Update release. $this->pdo->queryExec(sprintf(' UPDATE releases SET consoleinfoid = %d WHERE id = %d', $gameId, $arr['id'])); // Sleep to not flood amazon. $diff = floor((microtime(true) - $startTime) * 1000000); if ($this->sleeptime * 1000 - $diff > 0 && $usedAmazon === true) { usleep($this->sleeptime * 1000 - $diff); } } } else { if ($this->echooutput) { $this->pdo->log->doEcho($this->pdo->log->header('No console releases to process.')); } } }
/** * Retrieve alternate release with same or similar searchname * * @param string $guid * @param string $searchname * @param string $userid * @return string */ public function getAlternate($guid, $searchname, $userid) { //status values // 0/false = successfully downloaded // 1/true = failed download $this->pdo->queryInsert(sprintf("INSERT IGNORE INTO dnzb_failures (userid, guid) VALUES (%d, %s)", $userid, $this->pdo->escapeString($guid))); $alternate = $this->pdo->queryOneRow(sprintf('SELECT * FROM releases r WHERE r.searchname %s AND r.guid NOT IN (SELECT guid FROM failed_downloads WHERE userid = %d)', $this->pdo->likeString($searchname), $userid)); return $alternate; }
/** * Gets the completion from the NZB, optionally looks if there is an NFO/PAR2 file. * * @param string $guid * @param int $relID * @param int $groupID * @param bool $nfoCheck * * @return array|bool * * @access public */ public function parseNZB($guid, $relID, $groupID, $nfoCheck = false) { $nzbFile = $this->LoadNZB($guid); if ($nzbFile !== false) { $messageID = $hiddenID = ''; $actualParts = $artificialParts = 0; $foundPAR2 = $this->lookuppar2 === false ? true : false; $foundNFO = $hiddenNFO = $nfoCheck === false ? true : false; foreach ($nzbFile->file as $nzbcontents) { foreach ($nzbcontents->segments->segment as $segment) { $actualParts++; } $subject = (string) $nzbcontents->attributes()->subject; if (preg_match('/(\\d+)\\)$/', $subject, $parts)) { $artificialParts += $parts[1]; } if ($foundNFO === false) { if (preg_match('/\\.\\b(nfo|inf|ofn)\\b(?![ .-])/i', $subject)) { $messageID = (string) $nzbcontents->segments->segment; $foundNFO = true; } } if ($foundNFO === false && $hiddenNFO === false) { if (preg_match('/\\(1\\/1\\)$/i', $subject) && !preg_match('/\\.(apk|bat|bmp|cbr|cbz|cfg|css|csv|cue|db|dll|doc|epub|exe|gif|htm|ico|idx|ini' . '|jpg|lit|log|m3u|mid|mobi|mp3|nib|nzb|odt|opf|otf|par|par2|pdf|psd|pps|png|ppt|r\\d{2,4}' . '|rar|sfv|srr|sub|srt|sql|rom|rtf|tif|torrent|ttf|txt|vb|vol\\d+\\+\\d+|wps|xml|zip)/i', $subject)) { $hiddenID = (string) $nzbcontents->segments->segment; $hiddenNFO = true; } } if ($foundPAR2 === false) { if (preg_match('/\\.(par[2" ]|\\d{2,3}").+\\(1\\/1\\)$/i', $subject)) { if ($this->pp->parsePAR2((string) $nzbcontents->segments->segment, $relID, $groupID, $this->nntp, 1) === true) { $this->pdo->queryExec(sprintf('UPDATE releases SET proc_par2 = 1 WHERE id = %d', $relID)); $foundPAR2 = true; } } } } if ($artificialParts <= 0 || $actualParts <= 0) { $completion = 0; } else { $completion = $actualParts / $artificialParts * 100; } if ($completion > 100) { $completion = 100; } $this->pdo->queryExec(sprintf('UPDATE releases SET completion = %d WHERE id = %d', $completion, $relID)); if ($foundNFO === true && strlen($messageID) > 1) { return ['hidden' => false, 'ID' => $messageID]; } elseif ($hiddenNFO === true && strlen($hiddenID) > 1) { return ['hidden' => true, 'ID' => $hiddenID]; } } return false; }
/** * Check if Tmux is running, stop it if it is. * * @return bool * @access public */ public function isRunning() { if ($this->get()->running == 1) { $this->pdo->queryExec("UPDATE tmux SET value = '0' WHERE setting = 'RUNNING'"); $sleep = $this->get()->monitor_delay; echo $this->pdo->log->header("Stopping tmux scripts and waiting {$sleep} seconds for all panes to shutdown"); sleep($sleep); return true; } return false; }
/** * Get all groups in the DB. * * @return bool * @access protected */ protected function getAllGroups() { $this->allGroups = []; $groups = $this->pdo->query("SELECT id, name FROM groups"); foreach ($groups as $group) { $this->allGroups[$group["name"]] = $group["id"]; } if (count($this->allGroups) === 0) { $this->echoOut('You have no groups in your database!'); return false; } return true; }
/** * Add new files for a release ID. * * @param int $id The ID of the release. * @param string $name Name of the file. * @param int $size Size of the file. * @param int $createdTime Unix time the file was created. * @param int $hasPassword Does it have a password (see Releases class constants)? * * @return mixed */ public function add($id, $name, $size, $createdTime, $hasPassword) { $duplicateCheck = $this->pdo->queryOneRow(sprintf(' SELECT id FROM release_files WHERE releaseid = %d AND name = %s', $id, $this->pdo->escapeString(utf8_encode($name)))); if ($duplicateCheck === false) { return $this->pdo->queryInsert(sprintf("\n\t\t\t\t\tINSERT INTO release_files\n\t\t\t\t\t(releaseid, name, size, createddate, passworded)\n\t\t\t\t\tVALUES\n\t\t\t\t\t(%d, %s, %s, %s, %d)", $id, $this->pdo->escapeString(utf8_encode($name)), $this->pdo->escapeString($size), $this->pdo->from_unixtime($createdTime), $hasPassword)); } return 0; }
/** * Checks if a user is a specific role. * * @notes Uses type of $user to denote identifier. if string: username, if int: userid * @param int $roleID * @param string|int $user * @return bool */ public function roleCheck($roleID, $user) { if (is_string($user) && strlen($user) > 0) { $user = $this->pdo->escapeString($user); $querySuffix = "username = {$user}"; } elseif (is_int($user) && $user >= 0) { $querySuffix = "id = {$user}"; } else { return false; } $result = $this->pdo->queryOneRow(sprintf("SELECT role FROM users WHERE %s", $querySuffix)); return (int) $result['role'] == (int) $roleID ? true : false; }
/** * Check if the tables exists for the group_id, make new tables for table per group. * * @param int $groupID * * @return bool */ public function createNewTPGTables($groupID) { foreach (['collections', 'binaries', 'parts', 'partrepair'] as $tableName) { if ($this->pdo->queryExec(sprintf('SELECT * FROM %s_%s LIMIT 1', $tableName, $groupID), true) === false) { if ($this->pdo->queryExec(sprintf('CREATE TABLE %s_%s LIKE %s', $tableName, $groupID, $tableName), true) === false) { return false; } else { if ($tableName === 'collections') { $this->pdo->queryExec(sprintf('CREATE TRIGGER delete_collections_%s BEFORE DELETE ON collections_%s FOR EACH ROW BEGIN' . ' DELETE FROM binaries_%s WHERE collectionid = OLD.id; DELETE FROM parts_%s WHERE collection_id = OLD.id; END', $groupID, $groupID, $groupID, $groupID)); } } } } return true; }
/** * Directs flow for updating child AniDB tables * * @param array $AniDBInfoArray */ private function updateAniChildTables($AniDBInfoArray = []) { $check = $this->pdo->queryOneRow(sprintf(' SELECT ai.anidbid AS info FROM anidb_info ai WHERE ai.anidbid = %d', $this->anidbId)); if ($check === false) { $picture = $this->insertAniDBInfoEps($AniDBInfoArray); } else { $picture = $this->updateAniDBInfoEps($AniDBInfoArray); } if (!empty($picture) && !file_exists($this->imgSavePath . $this->anidbId . ".jpg")) { (new ReleaseImage($this->pdo))->saveImage($this->anidbId, 'http://img7.anidb.net/pics/anime/' . $picture, $this->imgSavePath); } }
/** * 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'))); $collections = $this->pdo->queryDirect($this->_collectionsQuery . $relID); if ($collections instanceof \Traversable) { foreach ($collections as $collection) { $poster = htmlspecialchars($collection['fromname'], ENT_QUOTES, 'utf-8'); $binaries = $this->pdo->queryDirect(sprintf($this->_binariesQuery, $collection['id'])); if ($binaries instanceof \Traversable) { foreach ($binaries as $binary) { // Buffer segment writes, increases performance. $string = ''; $parts = $this->pdo->queryDirect(sprintf($this->_partsQuery, $binary['id'])); if ($parts instanceof \Traversable) { foreach ($parts as $part) { if ($nzb_guid === '') { $nzb_guid = $part['messageid']; } $string .= ' <segment bytes="' . $part['size'] . '" number="' . $part['partnumber'] . '">' . htmlspecialchars($part['messageid'], ENT_QUOTES, 'utf-8') . "</segment>\n"; } } gzwrite($fp, '<file poster="' . $poster . '" date="' . $collection['udate'] . '" subject="' . htmlspecialchars($binary['name'], ENT_QUOTES, 'utf-8') . ' (1/' . $binary['totalparts'] . ")\">\n <groups>\n <group>" . $collection['groupname'] . "</group>\n </groups>\n <segments>\n" . $string . " </segments>\n</file>\n"); } } } } gzwrite($fp, '</nzb>'); gzclose($fp); if (is_file($path)) { // Mark release as having NZB and delete CBP. $this->pdo->queryExec(sprintf(' UPDATE releases SET nzbstatus = %d %s WHERE id = %d; DELETE c, b, p FROM %s c JOIN %s b ON(c.id=b.collection_id) STRAIGHT_JOIN %s p ON(b.id=p.binaryid) WHERE c.releaseid = %d', NZB::NZB_ADDED, $nzb_guid === '' ? '' : ', nzb_guid = UNHEX( ' . $this->pdo->escapestring(md5($nzb_guid)) . ' )', $relID, $this->_tableNames['cName'], $this->_tableNames['bName'], $this->_tableNames['pName'], $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; }