Ejemplo n.º 1
0
    /**
     * Test a single collection regex for a group name.
     *
     * Requires table per group to be on.
     *
     * @param string $groupName
     * @param string $regex
     * @param int    $limit
     *
     * @return array
     */
    public function testCollectionRegex($groupName, $regex, $limit)
    {
        $groups = new Groups(['Settings' => $this->pdo]);
        $groupID = $groups->getIDByName($groupName);
        if (!$groupID) {
            return [];
        }
        $tableNames = $groups->getCBPTableNames(true, $groupID);
        $rows = $this->pdo->query(sprintf('SELECT
					b.name, b.totalparts, b.currentparts, HEX(b.binaryhash) AS binaryhash,
					c.fromname, c.collectionhash
				FROM %s b
				INNER JOIN %s c ON c.id = b.collection_id', $tableNames['bname'], $tableNames['cname']));
        $data = [];
        if ($rows) {
            $limit--;
            $hashes = [];
            foreach ($rows as $row) {
                if (preg_match($regex, $row['name'], $matches)) {
                    ksort($matches);
                    $string = $string2 = '';
                    foreach ($matches as $key => $match) {
                        if (!is_int($key)) {
                            $string .= $match;
                            $string2 .= '<br/>' . $key . ': ' . $match;
                        }
                    }
                    $files = 0;
                    if (preg_match('/[[(\\s](\\d{1,5})(\\/|[\\s_]of[\\s_]|-)(\\d{1,5})[])\\s$:]/i', $row['name'], $fileCount)) {
                        $files = $fileCount[3];
                    }
                    $newCollectionHash = sha1($string . $row['fromname'] . $groupID . $files);
                    $data['New hash: ' . $newCollectionHash . $string2][$row['binaryhash']] = ['file_name' => $row['name'], 'file_total_parts' => $row['totalparts'], 'file_current_parts' => $row['currentparts'], 'collection_poster' => $row['fromname'], 'old_collection_hash' => $row['collectionhash']];
                    if ($limit > 0) {
                        if (count($hashes) > $limit) {
                            break;
                        }
                        $hashes[$newCollectionHash] = '';
                    }
                }
            }
        }
        return $data;
    }
Ejemplo n.º 2
0
    /**
     * Delete collections (complete/incomplete/old/etc).
     *
     * @param int|string $groupID (optional)
     *
     * @void
     * @access public
     */
    public function deleteCollections($groupID)
    {
        $startTime = time();
        $group = $this->groups->getCBPTableNames($this->tablePerGroup, $groupID);
        $deletedCount = 0;
        // CBP older than retention.
        if ($this->echoCLI) {
            echo $this->pdo->log->header("Process Releases -> Delete finished collections." . PHP_EOL) . $this->pdo->log->primary(sprintf('Deleting collections/binaries/parts older than %d hours.', $this->pdo->getSetting('partretentionhours')));
        }
        $deleted = 0;
        $deleteQuery = $this->pdo->queryExec(sprintf('DELETE c, b, p FROM %s c
				LEFT JOIN %s b ON (c.id=b.collection_id)
				LEFT JOIN %s p ON (b.id=p.binaryid)
				WHERE (c.dateadded < NOW() - INTERVAL %d HOUR) %s', $group['cname'], $group['bname'], $group['pname'], $this->pdo->getSetting('partretentionhours'), !empty($groupID) && $this->tablePerGroup === false ? ' AND c.group_id = ' . $groupID : ''));
        if ($deleteQuery !== false) {
            $deleted = $deleteQuery->rowCount();
            $deletedCount += $deleted;
        }
        $firstQuery = $fourthQuery = time();
        if ($this->echoCLI) {
            echo $this->pdo->log->primary('Finished deleting ' . $deleted . ' old collections/binaries/parts in ' . ($firstQuery - $startTime) . ' seconds.' . PHP_EOL);
        }
        // Cleanup orphaned collections, binaries and parts
        // this really shouldn't happen, but just incase - so we only run 1/200 of the time
        if (mt_rand(0, 200) <= 1) {
            // CBP collection orphaned with no binaries or parts.
            if ($this->echoCLI) {
                echo $this->pdo->log->header("Process Releases -> Remove CBP orphans." . PHP_EOL) . $this->pdo->log->primary('Deleting orphaned collections.');
            }
            $deleted = 0;
            $deleteQuery = $this->pdo->queryExec(sprintf('DELETE c, b, p FROM %s c
					LEFT JOIN %s b ON (c.id=b.collection_id)
					LEFT JOIN %s p ON (b.id=p.binaryid)
					WHERE (b.id IS NULL OR p.binaryid IS NULL) %s', $group['cname'], $group['bname'], $group['pname'], !empty($groupID) && $this->tablePerGroup === false ? ' AND c.group_id = ' . $groupID : ''));
            if ($deleteQuery !== false) {
                $deleted = $deleteQuery->rowCount();
                $deletedCount += $deleted;
            }
            $secondQuery = time();
            if ($this->echoCLI) {
                echo $this->pdo->log->primary('Finished deleting ' . $deleted . ' orphaned collections in ' . ($secondQuery - $firstQuery) . ' seconds.' . PHP_EOL);
            }
            // orphaned binaries - binaries with no parts or binaries with no collection
            // Don't delete currently inserting binaries by checking the max id.
            if ($this->echoCLI) {
                echo $this->pdo->log->primary('Deleting orphaned binaries/parts with no collection.');
            }
            $deleted = 0;
            $deleteQuery = $this->pdo->queryExec(sprintf('DELETE b, p FROM %s b
									LEFT JOIN %s p ON(b.id=p.binaryid)
									LEFT JOIN %s c ON(b.collection_id=c.id)
									WHERE (p.binaryid IS NULL OR c.id IS NULL) AND b.id < %d ', $group['bname'], $group['pname'], $group['cname'], $this->maxQueryFormulator($group['bname'], 20000)));
            if ($deleteQuery !== false) {
                $deleted = $deleteQuery->rowCount();
                $deletedCount += $deleted;
            }
            $thirdQuery = time();
            if ($this->echoCLI) {
                echo $this->pdo->log->primary('Finished deleting ' . $deleted . ' binaries with no collections or parts in ' . ($thirdQuery - $secondQuery) . ' seconds.');
            }
            // orphaned parts - parts with no binary
            // Don't delete currently inserting parts by checking the max id.
            if ($this->echoCLI) {
                echo $this->pdo->log->primary('Deleting orphaned parts with no binaries.');
            }
            $deleted = 0;
            $deleteQuery = $this->pdo->queryExec(sprintf('DELETE p FROM %s p LEFT JOIN %s b ON (p.binaryid=b.id) WHERE b.id IS NULL AND p.binaryid < %d', $group['pname'], $group['bname'], $this->maxQueryFormulator($group['bname'], 20000)));
            if ($deleteQuery !== false) {
                $deleted = $deleteQuery->rowCount();
                $deletedCount += $deleted;
            }
            $fourthQuery = time();
            if ($this->echoCLI) {
                echo $this->pdo->log->primary('Finished deleting ' . $deleted . ' parts with no binaries in ' . ($fourthQuery - $thirdQuery) . ' seconds.' . PHP_EOL);
            }
        }
        // done cleaning up Binaries/Parts orphans
        if ($this->echoCLI) {
            echo $this->pdo->log->primary('Deleting collections that were missed after NZB creation.');
        }
        $deleted = 0;
        // Collections that were missing on NZB creation.
        $collections = $this->pdo->queryDirect(sprintf('
				SELECT SQL_NO_CACHE c.id
				FROM %s c
				INNER JOIN releases r ON r.id = c.releaseid
				WHERE r.nzbstatus = 1', $group['cname']));
        if ($collections instanceof \Traversable) {
            foreach ($collections as $collection) {
                $deleted++;
                $this->pdo->queryExec(sprintf('
						DELETE c, b, p
						FROM %s c
						LEFT JOIN %s b ON(c.id=b.collection_id)
						LEFT JOIN %s p ON(b.id=p.binaryid)
						WHERE c.id = %d', $group['cname'], $group['bname'], $group['pname'], $collection['id']));
            }
            $deletedCount += $deleted;
        }
        if ($this->echoCLI) {
            $this->pdo->log->doEcho($this->pdo->log->primary('Finished deleting ' . $deleted . ' collections missed after NZB creation in ' . (time() - $fourthQuery) . ' seconds.' . PHP_EOL . 'Removed ' . number_format($deletedCount) . ' parts/binaries/collection rows in ' . $this->consoleTools->convertTime($fourthQuery - $startTime) . PHP_EOL));
        }
    }
Ejemplo n.º 3
0
    /**
     * Returns unix time for an article number.
     *
     * @param int    $post      The article number to get the time from.
     * @param array  $groupData Usenet group info from NNTP selectGroup method.
     *
     * @return int	Timestamp.
     */
    public function postdate($post, array $groupData)
    {
        // Set table names
        $groupID = $this->_groups->getIDByName($groupData['group']);
        $group = [];
        if ($groupID !== '') {
            $group = $this->_groups->getCBPTableNames($this->_tablePerGroup, $groupID);
        }
        $currentPost = $post;
        $attempts = $date = 0;
        do {
            // Try to get the article date locally first.
            if ($groupID !== '') {
                // Try to get locally.
                $local = $this->_pdo->queryOneRow(sprintf('
						SELECT c.date AS date
						FROM %s c
						INNER JOIN %s b ON(c.id=b.collection_id)
						INNER JOIN %s p ON(b.id=p.binaryid)
						WHERE p.number = %s
						%s LIMIT 1', $group['cname'], $group['bname'], $group['pname'], $currentPost, $this->_tablePerGroup === false ? sprintf('AND c.group_id = %d', $groupID) : ''));
                if ($local !== false) {
                    $date = $local['date'];
                    break;
                }
            }
            // If we could not find it locally, try usenet.
            $header = $this->_nntp->getXOVER($currentPost);
            if (!$this->_nntp->isError($header)) {
                // Check if the date is set.
                if (isset($header[0]['Date']) && strlen($header[0]['Date']) > 0) {
                    $date = $header[0]['Date'];
                    break;
                }
            }
            // Try to get a different article number.
            if (abs($currentPost - $groupData['first']) > abs($groupData['last'] - $currentPost)) {
                $tempPost = round($currentPost / (mt_rand(1005, 1012) / 1000), 0, PHP_ROUND_HALF_UP);
                if ($tempPost < $groupData['first']) {
                    $tempPost = $groupData['first'];
                }
            } else {
                $tempPost = round(mt_rand(1005, 1012) / 1000 * $currentPost, 0, PHP_ROUND_HALF_UP);
                if ($tempPost > $groupData['last']) {
                    $tempPost = $groupData['last'];
                }
            }
            // If we got the same article number as last time, give up.
            if ($tempPost === $currentPost) {
                break;
            }
            $currentPost = $tempPost;
            if ($this->_debug) {
                $this->_colorCLI->doEcho($this->_colorCLI->debug('Postdate retried ' . $attempts . " time(s)."));
            }
        } while ($attempts++ <= 20);
        // If we didn't get a date, set it to now.
        if (!$date) {
            $date = time();
        } else {
            $date = strtotime($date);
        }
        if ($this->_debug) {
            $this->_debugging->log(get_class(), __FUNCTION__, 'Article (' . $post . "'s) date is (" . $date . ') (' . $this->daysOld($date) . " days old)", Logger::LOG_INFO);
        }
        return $date;
    }
Ejemplo n.º 4
0
    /**
     * Delete collections (complete/incomplete/old/etc).
     *
     * @param int|string $groupID (optional)
     *
     * @void
     * @access public
     */
    public function deleteCollections($groupID)
    {
        $startTime = time();
        $group = $this->groups->getCBPTableNames($this->tablePerGroup, $groupID);
        $deletedCount = 0;
        if ($this->echoCLI) {
            echo $this->pdo->log->header("Process Releases -> Delete finished collections." . PHP_EOL) . $this->pdo->log->primary('Deleting old collections/binaries/parts.');
        }
        $deleted = 0;
        // CBP older than retention.
        $deleteQuery = $this->pdo->queryExec(sprintf('DELETE FROM %s WHERE dateadded < (NOW() - INTERVAL %d HOUR) %s', $group['cname'], $this->pdo->getSetting('partretentionhours'), !empty($groupID) && $this->tablePerGroup === false ? ' AND group_id = ' . $groupID : ''));
        if ($deleteQuery !== false) {
            $deleted = $deleteQuery->rowCount();
            $deletedCount += $deleted;
        }
        $firstQuery = time();
        if ($this->echoCLI) {
            echo $this->pdo->log->primary('Finished deleting ' . $deleted . ' old collections/binaries/parts in ' . ($firstQuery - $startTime) . ' seconds.' . PHP_EOL . 'Deleting binaries/parts with no collections.');
        }
        $deleted = 0;
        // Binaries/parts that somehow have no collection.
        $deleteQuery = $this->pdo->queryExec(sprintf('DELETE %s, %s FROM %s, %s WHERE %s.collection_id = 0 AND %s.id = %s.binaryid', $group['bname'], $group['pname'], $group['bname'], $group['pname'], $group['bname'], $group['bname'], $group['pname']));
        if ($deleteQuery !== false) {
            $deleted = $deleteQuery->rowCount();
            $deletedCount += $deleted;
        }
        $secondQuery = time();
        if ($this->echoCLI) {
            echo $this->pdo->log->primary('Finished deleting ' . $deleted . ' binaries/parts with no collections in ' . ($secondQuery - $firstQuery) . ' seconds.' . PHP_EOL . 'Deleting parts with no binaries.');
        }
        $deleted = 0;
        // Parts that somehow have no binaries. Don't delete parts currently inserting, by checking the max ID.
        if (mt_rand(0, 100) <= 5) {
            $deleteQuery = $this->pdo->queryExec(sprintf('DELETE FROM %s WHERE binaryid NOT IN (SELECT id FROM %s) %s', $group['pname'], $group['bname'], $this->minMaxQueryFormulator($group['pname'], 40000)));
            if ($deleteQuery !== false) {
                $deleted = $deleteQuery->rowCount();
                $deletedCount += $deleted;
            }
        }
        $thirdQuery = time();
        if ($this->echoCLI) {
            echo $this->pdo->log->primary('Finished deleting ' . $deleted . ' parts with no binaries in ' . ($thirdQuery - $secondQuery) . ' seconds.' . PHP_EOL . 'Deleting binaries with no collections.');
        }
        $deleted = 0;
        // Binaries that somehow have no collection. Don't delete currently inserting binaries by checking the max id.
        $deleteQuery = $this->pdo->queryExec(sprintf('DELETE FROM %s WHERE collection_id NOT IN (SELECT id FROM %s) %s', $group['bname'], $group['cname'], $this->minMaxQueryFormulator($group['bname'], 20000)));
        if ($deleteQuery !== false) {
            $deleted = $deleteQuery->rowCount();
            $deletedCount += $deleted;
        }
        $fourthQuery = time();
        if ($this->echoCLI) {
            echo $this->pdo->log->primary('Finished deleting ' . $deleted . ' binaries with no collections in ' . ($fourthQuery - $thirdQuery) . ' seconds.' . PHP_EOL . 'Deleting collections with no binaries.');
        }
        $deleted = 0;
        // Collections that somehow have no binaries.
        $collectionIDs = $this->pdo->queryDirect(sprintf('SELECT SQL_NO_CACHE id FROM %s WHERE id NOT IN (SELECT collection_id FROM %s) %s', $group['cname'], $group['bname'], $this->minMaxQueryFormulator($group['cname'], 10000)));
        if ($collectionIDs instanceof \Traversable) {
            foreach ($collectionIDs as $collectionID) {
                $deleted++;
                $this->pdo->queryExec(sprintf('DELETE FROM %s WHERE id = %d', $group['cname'], $collectionID['id']));
            }
            $deletedCount += $deleted;
        }
        $fifthQuery = time();
        if ($this->echoCLI) {
            echo $this->pdo->log->primary('Finished deleting ' . $deleted . ' collections with no binaries in ' . ($fifthQuery - $fourthQuery) . ' seconds.' . PHP_EOL . 'Deleting collections that were missed after NZB creation.');
        }
        $deleted = 0;
        // Collections that were missing on NZB creation.
        $collections = $this->pdo->queryDirect(sprintf('
				SELECT SQL_NO_CACHE c.id
				FROM %s c
				INNER JOIN releases r ON r.id = c.releaseid
				WHERE r.nzbstatus = 1', $group['cname']));
        if ($collections instanceof \Traversable) {
            foreach ($collections as $collection) {
                $deleted++;
                $this->pdo->queryExec(sprintf('
						DELETE FROM %s WHERE id = %d', $group['cname'], $collection['id']));
            }
            $deletedCount += $deleted;
        }
        if ($this->echoCLI) {
            $this->pdo->log->doEcho($this->pdo->log->primary('Finished deleting ' . $deleted . ' collections missed after NZB creation in ' . (time() - $fifthQuery) . ' seconds.' . PHP_EOL . 'Removed ' . number_format($deletedCount) . ' parts/binaries/collection rows in ' . $this->consoleTools->convertTime($fifthQuery - $startTime) . PHP_EOL));
        }
    }