/** * Create releases from complete binaries. * * @param int|string $groupID (optional) * * @return int * @access public */ public function createReleases($groupID) { $startTime = time(); $group = $this->groups->getCBPTableNames($this->tablePerGroup, $groupID); $page = new Page(); $this->pdo->log->doEcho($this->pdo->log->primary('Creating releases from complete binaries')); $this->pdo->ping(true); // // Get out all distinct relname, group from binaries // $categorize = new \Categorize(['Settings' => $this->pdo]); $returnCount = $duplicate = 0; $result = $this->pdo->queryDirect(sprintf("SELECT %s.*, g.name AS group_name, count(%s.id) AS parts FROM %s INNER JOIN groups g ON g.id = %s.groupid WHERE %s procstat = %d AND relname IS NOT NULL GROUP BY relname, g.name, groupid, fromname ORDER BY COUNT(%s.id) DESC LIMIT %d", $group['bname'], $group['bname'], $group['bname'], $group['bname'], !empty($groupID) ? ' groupid = ' . $groupID . ' AND ' : ' ', Releases::PROCSTAT_READYTORELEASE, $group['bname'], $this->releaseCreationLimit)); while ($row = $this->pdo->getAssocArray($result)) { $relguid = $this->createGUID(); // Clean release name $releaseCleaning = new ReleaseCleaning(); $cleanRelName = $this->cleanReleaseName($row['relname']); $cleanedName = $releaseCleaning->releaseCleaner($row['relname'], $row['fromname'], $row['group_name']); if (is_array($cleanedName)) { $properName = $cleanedName['properlynamed']; $prehashID = isset($cleanerName['predb']) ? $cleanerName['predb'] : false; $isReqID = isset($cleanerName['requestid']) ? $cleanerName['requestid'] : false; $cleanedName = $cleanedName['cleansubject']; } else { $properName = true; $isReqID = $prehashID = false; } if ($prehashID === false && $cleanedName !== '') { // try to match the cleaned searchname to predb title or filename here $preHash = new PreHash(); $preMatch = $preHash->matchPre($cleanedName); if ($preMatch !== false) { $cleanedName = $preMatch['title']; $prehashID = $preMatch['prehashid']; $properName = true; } } $relid = $this->insertRelease(['name' => $this->pdo->escapeString($cleanRelName), 'searchname' => $this->pdo->escapeString(utf8_encode($cleanedName)), 'totalpart' => $row["parts"], 'groupid' => $row["groupid"], 'guid' => $this->pdo->escapeString($relguid), 'categoryid' => $categorize->determineCategory($groupID, $cleanedName), 'regexid' => $row["regexid"], 'postdate' => $this->pdo->escapeString($row['date']), 'fromname' => $this->pdo->escapeString($row['fromname']), 'reqid' => $row["reqid"], 'passwordstatus' => $page->settings->getSetting('checkpasswordedrar') > 0 ? -1 : 0, 'nzbstatus' => \Enzebe::NZB_NONE, 'isrenamed' => $properName === true ? 1 : 0, 'reqidstatus' => $isReqID === true ? 1 : 0, 'prehashid' => $prehashID === false ? 0 : $prehashID]); // // Tag every binary for this release with its parent release id // $this->pdo->queryExec(sprintf("UPDATE %s SET procstat = %d, releaseid = %d WHERE relname = %s AND procstat = %d AND %s fromname=%s", $group['bname'], Releases::PROCSTAT_RELEASED, $relid, $this->pdo->escapeString($row["relname"]), Releases::PROCSTAT_READYTORELEASE, !empty($groupID) ? ' groupid = ' . $groupID . ' AND ' : ' ', $this->pdo->escapeString($row["fromname"]))); $cat = new \Categorize(['Settings' => $this->pdo]); // // Write the nzb to disk // $catId = $cat->determineCategory($groupID, $cleanRelName); $nzbfile = $this->nzb->getNZBPath($relguid, $page->settings->getSetting('nzbpath'), true); $this->nzb->writeNZBforreleaseID($relid, $cleanRelName, $catId, $nzbfile, $groupID); // // Remove used binaries // $this->pdo->queryDelete(sprintf("DELETE %s, %s FROM %s JOIN %s ON %s.id = %s.binaryid WHERE releaseid = %d ", $group['pname'], $group['bname'], $group['pname'], $group['bname'], $group['bname'], $group['pname'], $relid)); // // If nzb successfully written, then load it and get size completion from it // $nzbInfo = new NZBInfo(); if (!$nzbInfo->loadFromFile($nzbfile)) { $this->pdo->log->doEcho($this->pdo->log->primary('Failed to write nzb file (bad perms?) ' . $nzbfile . '')); $this->delete($relid); } else { // Check if gid already exists $dupes = $this->pdo->queryOneRow(sprintf("SELECT EXISTS(SELECT 1 FROM releases WHERE gid = %s) AS total", $this->pdo->escapeString($nzbInfo->gid))); if ($dupes['total'] > 0) { $this->pdo->log->doEcho($this->pdo->log->primary('Duplicate - ' . $cleanRelName . '')); $this->delete($relid); $duplicate++; } else { $this->pdo->queryExec(sprintf("UPDATE releases SET totalpart = %d, size = %s, COMPLETION = %d, GID=%s , nzb_guid = %s WHERE id = %d", $nzbInfo->filecount, $nzbInfo->filesize, $nzbInfo->completion, $this->pdo->escapeString($nzbInfo->gid), $this->pdo->escapeString($nzbInfo->gid), $relid)); $this->pdo->log->doEcho($this->pdo->log->primary('Added release ' . $cleanRelName . '')); $returnCount++; if ($this->echoCLI) { $this->pdo->log->doEcho($this->pdo->log->primary('Added ' . $returnCount . 'releases.')); } } } } if ($this->echoCLI) { $this->pdo->log->doEcho($this->pdo->log->primary(PHP_EOL . number_format($returnCount) . ' Releases added and ' . number_format($duplicate) . ' duplicate releases deleted in ' . $this->consoleTools->convertTime(time() - $startTime)), true); } return ['added' => $returnCount, 'dupes' => $duplicate]; }
public function processGID($limit = 500, $batch = 5000, $delete_broken_releases = false) { // Process until someone presses cntrl-c $db = new Settings(); $nzb = new NZB(); $processed = 0; // We need an offset for tracking unhandled issues $offset = 0; $fsql = 'SELECT id, name, guid FROM releases ' . 'WHERE gid IS NULL ORDER BY adddate DESC LIMIT %d,%d'; $usql = "UPDATE releases SET gid = '%s' WHERE id = %d"; while (1) { // finish if ($limit > 0 && $processed >= $limit) { break; } $batch = $limit > 0 && $batch > $limit ? $limit : $batch; $res = $db->query(sprintf($fsql, $offset, $batch)); if (!$res) { break; } if (count($res) <= 0) { break; } $offset += $batch; foreach ($res as $r) { $nzbfile = $nzb->getNZBPath($r["guid"]); if ($nzbfile === Null) { continue; } $nzbInfo = new NZBInfo(); if (!$nzbInfo->loadFromFile($nzbfile)) { if ($delete_broken_releases) { $release = new Releases(); $release->deleteSingle(['g' => $r['guid'], 'i' => $r['id']], $this->nzb, $this->releaseImage); // Free the variable in an attempt to recover memory unset($release); echo '-'; } else { // Skip over this one for future fetches $offset++; } continue; } $gid = false; if (!empty($nzbInfo->gid)) { $gid = $nzbInfo->gid; } // Free the variable in an attempt to recover memory unset($nzbInfo); if (!$gid) { if ($delete_broken_releases) { $release = new Releases(); $release->{$release}->deleteSingle(['g' => $r['guid'], 'i' => $r['id']], $this->nzb, $this->releaseImage); unset($release); echo '-'; } else { // Skip over this one for future fetches $offset++; } continue; } // Update DB With Global Identifer $ures = $db->queryExec(sprintf("UPDATE releases SET gid = %s WHERE id = %d", $db->escapeString($gid), $r['id'])); if ($ures->rowCount() == 0) { printf("\nPostPrc : Failed to update: %s\n", $r['name']); } // make noise... echo '.'; $processed += 1; } } # Batch update for comment table /*$usql = 'UPDATE release_comments, releases ' .'SET release_comments.gid = releases.gid, ' .'release_comments.nzb_guid = releases.nzb_guid ' .'WHERE releases.id = release_comments.releaseid ' .'AND release_comments.gid IS NULL ' .'AND release_comments.nzb_guid = "" ' .'AND releases.nzb_guid IS NOT NULL ' .'AND releases.gid IS NOT NULL ';*/ $affected = $db->queryExec(sprintf('UPDATE release_comments, releases SET release_comments.gid = releases.gid, release_comments.nzb_guid = releases.nzb_guid WHERE releases.id = release_comments.releaseid AND release_comments.gid IS NULL AND release_comments.nzb_guid = "" AND releases.nzb_guid IS NOT NULL AND releases.gid IS NOT NULL ')); $rows = $affected->rowCount(); if ($rows > 0) { $processed += $rows; } return $processed; }