Files
newznab-tmux/misc/update/multiprocessing/.do_not_run/switch.php
T
2024-10-28 11:29:09 +01:00

430 lines
14 KiB
PHP

<?php
if (! isset($argv[1])) {
exit('This script is not intended to be run manually.'.PHP_EOL);
}
require_once dirname(__DIR__, 4).DIRECTORY_SEPARATOR.'bootstrap/autoload.php';
use App\Models\Settings;
use App\Models\UsenetGroup;
use Blacklight\Backfill;
use Blacklight\Binaries;
use Blacklight\Nfo;
use Blacklight\NNTP;
use Blacklight\processing\post\ProcessAdditional;
use Blacklight\processing\PostProcess;
use Blacklight\processing\ProcessReleases;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
// The type of process we want to do: $options[1] => (string): releases
$options = explode(' ', $argv[1]);
switch ($options[1]) {
// Runs backFill interval or all.
// $options[2] => (string)group name, Name of group to work on.
// $options[3] => (int) backfill type from tmux settings. 1 = Backfill interval , 2 = Bakfill all
case 'backfill':
if (in_array((int) $options[3], [1, 2], false)) {
$value = (int) Settings::settingValue('site.tmux.backfill_qty');
if ($value !== null) {
try {
$nntp = nntp();
} catch (Throwable $e) {
Log::error($e->getTraceAsString());
echo $e->getMessage();
}
try {
(new Backfill())->backfillAllGroups($options[2], ($options[3] == 1 ? '' : $value['value']));
} catch (Throwable $e) {
Log::error($e->getTraceAsString());
echo $e->getMessage();
}
}
}
break;
/* BackFill up to x number of articles for all groups.
*
* $options[2] => (string) Group name.
* $options[3] => (int) Quantity of articles to download.
*/
case 'backfill_all_quantity':
try {
$nntp = nntp();
} catch (Throwable $e) {
Log::error($e->getTraceAsString());
echo $e->getMessage();
}
try {
(new Backfill())->backfillAllGroups($options[2], $options[3]);
} catch (Throwable $e) {
Log::error($e->getTraceAsString());
echo $e->getMessage();
}
break;
// BackFill a single group, 10000 parts.
// $options[2] => (string)group name, Name of group to work on.
case 'backfill_all_quick':
try {
$nntp = nntp();
} catch (Throwable $e) {
Log::error($e->getTraceAsString());
echo $e->getMessage();
}
try {
(new Backfill())->backfillAllGroups($options[2], 10000, 'normal');
} catch (Throwable $e) {
Log::error($e->getTraceAsString());
echo $e->getMessage();
}
break;
/* Get a range of article headers for a group.
*
* $options[2] => (string) backfill/binaries
* $options[3] => (string) Group name.
* $options[4] => (int) First article number in range.
* $options[5] => (int) Last article number in range.
* $options[6] => (int) Number of threads.
*/
case 'get_range':
try {
$nntp = nntp();
} catch (Throwable $e) {
echo $e->getMessage();
}
$groupMySQL = UsenetGroup::getByName($options[3])->toArray();
try {
if ($nntp::isError($nntp->selectGroup($groupMySQL['name'])) && $nntp::isError($nntp->dataError($nntp, $groupMySQL['name']))) {
return;
}
} catch (Throwable $e) {
Log::error($e->getTraceAsString());
echo $e->getMessage();
}
try {
$binaries = new Binaries(['NNTP' => $nntp, 'Groups' => null]);
$return = $binaries->scan($groupMySQL, $options[4], $options[5], ((int) Settings::settingValue('..safepartrepair') === 1 ? 'update' : 'backfill'));
} catch (Throwable $e) {
Log::error($e->getTraceAsString());
echo $e->getMessage();
}
if (empty($return)) {
exit();
}
$columns = [];
switch ($options[2]) {
case 'binaries':
if ($return['lastArticleNumber'] <= $groupMySQL['last_record']) {
exit();
}
$unixTime = is_numeric($return['lastArticleDate']) ? $return['lastArticleDate'] : strtotime($return['lastArticleDate']);
$columns[1] = sprintf(
'last_record_postdate = FROM_UNIXTIME(%s)',
$unixTime
);
$columns[2] = sprintf('last_record = %s', $return['lastArticleNumber']);
$query = sprintf(
'UPDATE usenet_groups SET %s, %s, last_updated = NOW() WHERE id = %d AND last_record < %s',
$columns[1],
$columns[2],
$groupMySQL['id'],
$return['lastArticleNumber']
);
break;
case 'backfill':
if ($return['firstArticleNumber'] >= $groupMySQL['first_record']) {
exit();
}
$unixTime = is_numeric($return['firstArticleDate']) ? $return['firstArticleDate'] : strtotime($return['firstArticleDate']);
$columns[1] = sprintf(
'first_record_postdate = FROM_UNIXTIME(%s)',
$unixTime
);
$columns[2] = sprintf('first_record = %s', $return['firstArticleNumber']);
$query = sprintf(
'UPDATE usenet_groups SET %s, %s, last_updated = NOW() WHERE id = %d AND first_record > %s',
$columns[1],
$columns[2],
$groupMySQL['id'],
$return['firstArticleNumber']
);
break;
default:
exit();
}
DB::update($query);
break;
/* Do part repair for a group.
*
* $options[2] => (string) Group name.
*/
case 'part_repair':
$groupMySQL = UsenetGroup::getByName($options[2])->toArray();
try {
$nntp = nntp();
} catch (Throwable $e) {
echo $e->getMessage();
}
// Select group, here, only once
try {
$data = $nntp->selectGroup($groupMySQL['name']);
} catch (Throwable $e) {
echo $e->getMessage();
}
try {
if ($nntp::isError($data) && $nntp->dataError($nntp, $groupMySQL['name']) === false) {
exit();
}
} catch (Throwable $e) {
echo $e->getMessage();
}
try {
(new Binaries(['NNTP' => $nntp]))->partRepair($groupMySQL);
} catch (Throwable $e) {
echo $e->getMessage();
}
break;
// Process releases.
// $options[2] => (string)groupCount, number of groups terminated by _ | (int)groupid, group to work on
case 'releases':
try {
$releases = new ProcessReleases();
} catch (Throwable $e) {
echo $e->getMessage();
}
//Runs function that are per group
if (is_numeric($options[2])) {
try {
processReleases($releases, $options[2]);
} catch (Throwable $e) {
echo $e->getMessage();
}
} else {
try {
processReleases($releases, '');
} catch (Throwable $e) {
echo $e->getMessage();
}
// Run functions that run on releases table after all others completed.
$groupCount = rtrim($options[2], '_');
if (! is_numeric($groupCount)) {
$groupCount = 1;
}
try {
$releases->deletedReleasesByGroup();
} catch (Throwable $e) {
echo $e->getMessage();
}
try {
$releases->deleteReleases();
} catch (Throwable $e) {
echo $e->getMessage();
}
//$releases->processRequestIDs('', (5000 * $groupCount), true);
//$releases->processRequestIDs('', (1000 * $groupCount), false);
try {
$releases->categorizeReleases(2);
} catch (Throwable $e) {
echo $e->getMessage();
}
}
break;
/* Update a single group's article headers.
*
* $options[2] => (string) Group name.
*/
case 'update_group_headers':
try {
$nntp = nntp();
} catch (Throwable $e) {
echo $e->getMessage();
}
$groupMySQL = UsenetGroup::getByName($options[2])->toArray();
try {
(new Binaries(['NNTP' => $nntp]))->updateGroup($groupMySQL);
} catch (Throwable $e) {
echo $e->getMessage();
}
break;
// Do a single group (update_binaries/backFill/update_releases/postprocess).
// $options[2] => (int)groupid, group to work on
case 'update_per_group':
if (is_numeric($options[2])) {
// Get the group info from MySQL.
$groupMySQL = UsenetGroup::find($options[2])->toArray();
if ($groupMySQL === null) {
exit('ERROR: Group not found with id '.$options[2].PHP_EOL);
}
// Connect to NNTP.
try {
$nntp = nntp();
} catch (Throwable $e) {
echo $e->getMessage();
}
try {
$backFill = new Backfill();
} catch (Throwable $e) {
echo $e->getMessage();
}
// Update the group for new binaries.
try {
(new Binaries())->updateGroup($groupMySQL);
} catch (Throwable $e) {
echo $e->getMessage();
}
// BackFill the group with 20k articles.
try {
$backFill->backfillAllGroups($groupMySQL['name'], 20000, 'normal');
} catch (Throwable $e) {
echo $e->getMessage();
}
// Create releases.
try {
processReleases(new ProcessReleases(), $options[2]);
} catch (Throwable $e) {
echo $e->getMessage();
}
// Post process the releases.
try {
(new ProcessAdditional(['Echo' => true, 'NNTP' => $nntp]))->start($options[2]);
} catch (Throwable $e) {
echo $e->getMessage();
}
try {
(new Nfo())->processNfoFiles($nntp, $options[2], '', (int) Settings::settingValue('..lookupimdb'), (int) Settings::settingValue('..lookuptvrage'));
} catch (Throwable $e) {
echo $e->getMessage();
}
}
break;
// Post process additional and NFO.
// $options[2] => (char)Letter or number a-f 0-9, first character of release guid.
case 'pp_additional':
case 'pp_nfo':
if (charCheck($options[2])) {
// Create the connection here and pass, this is for post processing, so check for alternate.
try {
$nntp = nntp();
} catch (Throwable $e) {
echo $e->getMessage();
}
if ($options[1] === 'pp_nfo') {
try {
(new Nfo())->processNfoFiles($nntp, '', $options[2], (int) Settings::settingValue('..lookupimdb'), (int) Settings::settingValue('..lookuptvrage'));
} catch (Throwable $e) {
echo $e->getMessage();
}
} else {
try {
(new ProcessAdditional(['Echo' => true, 'NNTP' => $nntp]))->start('', $options[2]);
} catch (Throwable $e) {
echo $e->getMessage();
}
}
}
break;
/* Post process movies.
*
* $options[2] (char) Single character, first letter of release guid.
* $options[3] (int) Process all releases or renamed releases only.
*/
case 'pp_movie':
if (charCheck($options[2])) {
try {
(new PostProcess())->processMovies('', $options[2], $options[3] ?? '');
} catch (Throwable $e) {
echo $e->getMessage();
}
}
break;
/* Post process TV.
*
* $options[2] (char) Single character, first letter of release guid.
* $options[3] (int) Process all releases or renamed releases only.
*/
case 'pp_tv':
if (charCheck($options[2])) {
try {
(new PostProcess())->processTv('', $options[2], $options[3] ?? '');
} catch (Throwable $e) {
echo $e->getMessage();
}
}
break;
}
/**
* Create / process releases for a groupID.
*
* @param $groupID
* @param ProcessReleases $releases
*
* @throws \Throwable
*/
function processReleases(ProcessReleases $releases, $groupID): void
{
$releaseCreationLimit = (Settings::settingValue('..maxnzbsprocessed') !== '' ? (int) Settings::settingValue('..maxnzbsprocessed') : 1000);
$releases->processIncompleteCollections($groupID);
$releases->processCollectionSizes($groupID);
$releases->deleteUnwantedCollections($groupID);
do {
$releasesCount = $releases->createReleases($groupID);
$nzbFilesAdded = $releases->createNZBs($groupID);
// This loops as long as the number of releases or nzbs added was >= the limit (meaning there are more waiting to be created)
} while ($releasesCount['added'] + $releasesCount['dupes'] >= $releaseCreationLimit || $nzbFilesAdded >= $releaseCreationLimit);
$releases->deleteCollections($groupID);
}
/**
* Check if the character contains a-f or 0-9.
*
* @param string $char
* @return bool
*/
function charCheck(string $char): bool
{
return \in_array($char, ['a', 'b', 'c', 'd', 'e', 'f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], true);
}
/**
* Connect to usenet, return NNTP object.
*
* @return NNTP
*
* @throws \Exception
*/
function &nntp(): NNTP
{
$nntp = new NNTP();
if ((config('nntmux_nntp.use_alternate_nntp_server') === true ? $nntp->doConnect(false, true) : $nntp->doConnect()) !== true) {
exit('ERROR: Unable to connect to usenet.'.PHP_EOL);
}
return $nntp;
}