mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-29 17:28:55 +00:00
1279 lines
37 KiB
PHP
1279 lines
37 KiB
PHP
<?php
|
|
require_once(WWW_DIR . "/lib/framework/db.php");
|
|
require_once(WWW_DIR . "/lib/category.php");
|
|
require_once(WWW_DIR . "/lib/releases.php");
|
|
require_once(WWW_DIR . "/lib/releaseimage.php");
|
|
require_once(WWW_DIR . "/lib/nzb.php");
|
|
require_once(WWW_DIR . "/lib/rarinfo/par2info.php");
|
|
require_once(WWW_DIR . "/lib/rarinfo/archiveinfo.php");
|
|
require_once(WWW_DIR . "/lib/rarinfo/zipinfo.php");
|
|
require_once(WWW_DIR . "/lib/nfo.php");
|
|
require_once(WWW_DIR . "/lib/site.php");
|
|
require_once(WWW_DIR . "/lib/util.php");
|
|
require_once(WWW_DIR . "/lib/groups.php");
|
|
require_once(WWW_DIR . '/lib/nntp.php');
|
|
require_once(WWW_DIR . "/lib/postprocess.php");
|
|
require_once(WWW_DIR . "/lib/Tmux.php");
|
|
require_once(WWW_DIR . "/lib/ColorCLI.php");
|
|
require_once(WWW_DIR . "/lib/ConsoleTools.php");
|
|
require_once("nzbcontents.php");
|
|
require_once("namefixer.php");
|
|
require_once("TraktTv.php");
|
|
require_once("Enzebe.php");
|
|
|
|
|
|
//*addedd from nZEDb for testing
|
|
|
|
class Functions
|
|
|
|
{
|
|
function __construct($echooutput = true)
|
|
{
|
|
$s = new Sites();
|
|
$this->site = $s->get();
|
|
$t = new Tmux();
|
|
$this->tmux = $t->get();
|
|
$this->p = new Postprocess();
|
|
$this->echooutput = $echooutput;
|
|
$this->c = new ColorCLI();
|
|
$this->db = new DB();
|
|
$this->groups = new Groups();
|
|
$this->m = new Movie();
|
|
$this->consoleTools = new ConsoleTools();
|
|
$this->tmpPath = $this->site->tmpunrarpath;
|
|
$this->sleeptime = (!empty($this->tmux->amazonsleep)) ? $this->tmux->amazonsleep : 1000;
|
|
$this->DEBUG_ECHO = ($this->tmux->debuginfo == '0') ? false : true;
|
|
if (defined('DEBUG_ECHO') && DEBUG_ECHO == true) {
|
|
$this->DEBUG_ECHO = true;
|
|
}
|
|
$this->debug = ($this->tmux->debuginfo == "0") ? false : true;
|
|
|
|
$this->compressedHeaders = ($this->site->compressedheaders == '1') ? true : false;
|
|
$this->safepartrepair = (!empty($this->tmux->safepartrepair)) ? $this->tmux->safepartrepair : 0;
|
|
$this->safebdate = (!empty($this->tmux->safebackfilldate)) ? $this->tmux->safebackfilldate : '2012 - 06 - 24';
|
|
$this->DoPartRepair = ($this->tmux->partrepair == '0') ? false : true;
|
|
$this->messagebuffer = (!empty($this->site->maxmssgs)) ? (int)$this->site->maxmssgs : 20000;
|
|
$this->NewGroupScanByDays = ($this->site->newgroupscanmethod == '1') ? true : false;
|
|
$this->NewGroupMsgsToScan = (!empty($this->site->newgroupmsgstoscan)) ? (int)$this->site->newgroupmsgstoscan : 50000;
|
|
$this->NewGroupDaysToScan = (!empty($this->site->newgroupdaystoscan)) ? (int)$this->site->newgroupdaystoscan : 3;
|
|
$this->partrepairlimit = (!empty($this->tmux->maxpartrepair)) ? (int)$this->tmux->maxpartrepair : 15000;
|
|
}
|
|
|
|
/**
|
|
* Should we use part repair?
|
|
*
|
|
* @var bool
|
|
*/
|
|
private
|
|
$DoPartRepair;
|
|
|
|
/**
|
|
* How many headers do we download per loop?
|
|
*
|
|
* @var int
|
|
*/
|
|
public
|
|
$messagebuffer;
|
|
|
|
/**
|
|
* How many days to go back on a new group?
|
|
*
|
|
* @var bool
|
|
*/
|
|
private
|
|
$NewGroupScanByDays;
|
|
|
|
|
|
function doecho($str)
|
|
{
|
|
if ($this->echooutput)
|
|
echo $this->c->header($str);
|
|
}
|
|
|
|
// Convert 2012-24-07 to 2012-07-24, there is probably a better way
|
|
public
|
|
function checkDate($date)
|
|
{
|
|
if (!empty($date) && $date != null) {
|
|
$chk = explode(" ", $date);
|
|
$chkd = explode("-", $chk[0]);
|
|
if ($chkd[1] > 12) {
|
|
$date = date('Y-m-d H:i:s', strtotime($chkd[1] . " " . $chkd[2] . " " . $chkd[0]));
|
|
}
|
|
|
|
return $date;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public
|
|
function updateReleaseHasPreview($guid)
|
|
{
|
|
$this->db->queryExec(sprintf('UPDATE releases SET haspreview = 1 WHERE guid = %s', $this->db->escapeString($guid)));
|
|
}
|
|
|
|
public
|
|
function debug($str)
|
|
{
|
|
if ($this->echooutput && $this->DEBUG_ECHO) {
|
|
echo $this->c->debug($str);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $group
|
|
* @param int $first
|
|
* @param int $type
|
|
* @param object $nntp
|
|
*
|
|
* @return void
|
|
*/
|
|
function getFinal($group, $first, $type, $nntp)
|
|
{
|
|
if (!isset($nntp)) {
|
|
exit($this->c->error("Not connected to usenet(backfill->getFinal).\n"));
|
|
}
|
|
|
|
$db = $this->db;
|
|
$groups = new Groups();
|
|
$groupArr = $groups->getByName($group);
|
|
|
|
// Select group, here, only once
|
|
$data = $nntp->selectGroup($groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
$data = $nntp->dataError($nntp, $groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ($type == 'Backfill') {
|
|
$postsdate = $this->postdate($nntp, $first, false, $group, true, 'oldest');
|
|
} else {
|
|
$postsdate = $this->postdate($nntp, $first, false, $group, true, 'newest');
|
|
}
|
|
$postsdate = $this->db->from_unixtime($postsdate);
|
|
|
|
if ($type == 'Backfill') {
|
|
$db->queryExec(sprintf('UPDATE groups SET first_record_postdate = %s, first_record = %s, last_updated = NOW() WHERE ID = %d', $postsdate, $db->escapeString($first), $groupArr['ID']));
|
|
} else {
|
|
$db->queryExec(sprintf('UPDATE groups SET last_record_postdate = %s, last_record = %s, last_updated = NOW() WHERE ID = %d', $postsdate, $db->escapeString($first), $groupArr['ID']));
|
|
}
|
|
|
|
$this->doecho(
|
|
$type .
|
|
' Safe Threaded for ' .
|
|
$group .
|
|
" completed." .
|
|
$this->c->rsetColor()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Returns a single timestamp from a local article number.
|
|
* If the article is missing, you can pass $old as true to return false (then use the last known date).
|
|
*
|
|
* @param object $nntp
|
|
* @param int $post
|
|
* @param bool $debug
|
|
* @param string $group
|
|
* @param bool $old
|
|
* @param string $type
|
|
*
|
|
* @return bool|int
|
|
*/
|
|
public
|
|
function postdate($nntp, $post, $debug = true, $group, $old = false, $type)
|
|
{
|
|
if (!isset($nntp)) {
|
|
$dmessage = "Not connected to usenet(backfill->postdate).";
|
|
|
|
|
|
$this->c->error($dmessage);
|
|
|
|
return false;
|
|
}
|
|
|
|
$db = $this->db;
|
|
$keeppost = $post;
|
|
|
|
$attempts = 0;
|
|
$success = $record = false;
|
|
do {
|
|
$msgs = $nntp->getOverview($post . "-" . $post, true, false);
|
|
$attempts++;
|
|
if (!$nntp->isError($msgs)) {
|
|
// Set table names
|
|
$groups = new Groups();
|
|
$groupID = $this->groups->getIDByName($group);
|
|
$groupa = array();
|
|
$groupa['bname'] = 'binaries';
|
|
$groupa['pname'] = 'parts';
|
|
if ((!isset($msgs[0]['Date']) || $msgs[0]['Date'] == '' || is_null($msgs[0]['Date'])) && $attempts == 0) {
|
|
$old_post = $post;
|
|
if ($type == 'newest') {
|
|
$res = $db->queryOneRow('SELECT p.number AS number FROM' . $groupa['bname'] . ' b, ' . $groupa['pname'] . ' p WHERE b.ID = b.releaseID AND b.ID = p.binaryID AND b.groupID = ' . $groupID . ' ORDER BY p.number DESC LIMIT 1');
|
|
if (isset($res['number']) && is_numeric($res['number'])) {
|
|
$post = $res['number'];
|
|
$dmessage =
|
|
"Unable to fetch article $old_post from " .
|
|
str_replace('alt.binaries', 'a.b', $group) .
|
|
". Retrying with newest article, from parts table, [$post] from ${groupa['pname']}";
|
|
|
|
$this->c->info($dmessage);
|
|
|
|
}
|
|
} else {
|
|
$res = $db->queryOneRow('SELECT p.number FROM ' . $groupa['bname'] . ' b, ' . $groupa['pname'] . ' p WHERE b.ID = p.binaryID AND b.groupID = ' . $groupID . ' ORDER BY p.number ASC LIMIT 1');
|
|
if (isset($res['number']) && is_numeric($res['number'])) {
|
|
$post = $res['number'];
|
|
$dmessage =
|
|
"Unable to fetch article $old_post from " .
|
|
str_replace('alt.binaries', 'a.b', $group) .
|
|
". Retrying with oldest article, from parts table, [$post] from ${groupa['pname']}.";
|
|
|
|
$this->c->info($dmessage);
|
|
|
|
}
|
|
}
|
|
$success = false;
|
|
}
|
|
if ((!isset($msgs[0]['Date']) || $msgs[0]['Date'] == '' || is_null($msgs[0]['Date'])) && $attempts != 0) {
|
|
if ($type == 'newest') {
|
|
$res = $db->queryOneRow('SELECT date FROM ' . $groupa['bname'] . ' ORDER BY date DESC LIMIT 1');
|
|
if (isset($res['date'])) {
|
|
$date = $res['date'];
|
|
$dmessage =
|
|
"Unable to fetch article $post from " .
|
|
str_replace('alt.binaries', 'a.b', $group) .
|
|
". Using newest date from ${groupa['bname']}.";
|
|
|
|
$this->c->info($dmessage);
|
|
|
|
if (strlen($date) > 0) {
|
|
$success = true;
|
|
}
|
|
}
|
|
} else {
|
|
$res = $db->queryOneRow('SELECT date FROM ' . $groupa['bname'] . ' ORDER BY date ASC LIMIT 1');
|
|
if (isset($res['date'])) {
|
|
$date = $res['date'];
|
|
$dmessage =
|
|
"Unable to fetch article $post from " .
|
|
str_replace('alt.binaries', 'a.b', $group) .
|
|
". Using oldest date from ${groupa['bname']}.";
|
|
|
|
$this->c->info($dmessage);
|
|
|
|
if (strlen($date) > 0) {
|
|
$success = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isset($msgs[0]['Date']) && $msgs[0]['Date'] != '' && $success === false) {
|
|
$date = $msgs[0]['Date'];
|
|
if (strlen($date) > 0) {
|
|
$success = true;
|
|
}
|
|
}
|
|
|
|
if ($attempts > 0) {
|
|
$this->c->debug('Retried ' . $attempts . " time(s).");
|
|
}
|
|
}
|
|
} while ($attempts <= 20 && $success === false);
|
|
|
|
if ($success === false && $old === true) {
|
|
if ($type == 'oldest') {
|
|
$res = $db->queryOneRow(sprintf("SELECT first_record_postdate from groups where name = '%s'", $group));
|
|
if (array_key_exists('first_record_postdate', $res)) {
|
|
$dmessage =
|
|
'Unable to fetch article ' .
|
|
$keeppost . ' from ' .
|
|
str_replace('alt.binaries', 'a.b', $group) .
|
|
'. Using current first_record_postdate[' .
|
|
$res['first_record_postdate'] .
|
|
"], instead.";
|
|
|
|
$this->c->info($dmessage);
|
|
|
|
return strtotime($res['first_record_postdate']);
|
|
} else {
|
|
return false;
|
|
}
|
|
} else {
|
|
$res = $db->queryOneRow(sprintf("SELECT last_record_postdate from groups where name = '%s'", $group));
|
|
if (array_key_exists('last_record_postdate', $res)) {
|
|
$dmessage =
|
|
'Unable to fetch article ' .
|
|
$keeppost . ' from ' .
|
|
str_replace('alt.binaries', 'a.b', $group) .
|
|
'. Using current last_record_postdate[' .
|
|
$res['last_record_postdate'] .
|
|
"], instead.";
|
|
|
|
$this->c->info($dmessage);
|
|
|
|
return strtotime($res['last_record_postdate']);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
} else if ($success === false) {
|
|
return false;
|
|
}
|
|
|
|
|
|
$date = strtotime($date);
|
|
|
|
return $date;
|
|
}
|
|
|
|
/**
|
|
* Backfill groups using user specified article count.
|
|
*
|
|
* @param object $nntp
|
|
* @param string $groupName
|
|
* @param string $articles
|
|
* @param string $type
|
|
*
|
|
* @return void
|
|
*/
|
|
public
|
|
function backfillPostAllGroups($nntp, $groupName = '', $articles = '', $type = '')
|
|
{
|
|
if (!isset($nntp)) {
|
|
$dmessage = "Not connected to usenet(backfill->backfillPostAllGroups).\n";
|
|
exit($this->c->error($dmessage));
|
|
}
|
|
|
|
$res = false;
|
|
$groups = new Groups();
|
|
if ($groupName != '') {
|
|
$grp = $groups->getByName($groupName);
|
|
if ($grp) {
|
|
$res = array($grp);
|
|
}
|
|
} else {
|
|
if ($type == 'normal') {
|
|
$res = $this->getActiveBackfill();
|
|
} else if ($type == 'date') {
|
|
$res = $this->getActiveByDateBackfill();
|
|
}
|
|
}
|
|
|
|
if ($res) {
|
|
$counter = 1;
|
|
$binaries = new Binaries();
|
|
foreach ($res as $groupArr) {
|
|
if ($groupName === '') {
|
|
$dmessage = "\nStarting group " . $counter . ' of ' . sizeof($res);
|
|
|
|
$this->c->header . $dmessage . $this->c->rsetColor();
|
|
}
|
|
$this->backfillPostGroup($nntp, $this->db, $binaries, $groupArr, sizeof($res) - $counter, $articles);
|
|
$counter++;
|
|
}
|
|
} else {
|
|
$dmessage = "No groups specified. Ensure groups are added to newznab's database for updating.";
|
|
|
|
$this->c->warning($dmessage);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $group
|
|
* @param int $first
|
|
* @param int $last
|
|
* @param int $threads
|
|
* @param object $nntp
|
|
*
|
|
* @return void
|
|
*/
|
|
public
|
|
function getRange($group, $first, $last, $threads, $nntp)
|
|
{
|
|
if (!isset($nntp)) {
|
|
exit($this->c->error("Not connected to usenet(backfill->getRange).\n"));
|
|
}
|
|
|
|
$groups = new Groups();
|
|
$this->startGroup = microtime(true);
|
|
$binaries = new Binaries();
|
|
$groupArr = $groups->getByName($group);
|
|
$process = $this->safepartrepair ? 'update' : 'backfill';
|
|
|
|
$this->c->header(
|
|
'Processing ' .
|
|
str_replace('alt.binaries', 'a.b', $groupArr['name']) .
|
|
(($this->compressedHeaders) ? ' Using Compression' : ' Not Using Compression') .
|
|
' ==> T-' .
|
|
$threads .
|
|
' ==> ' .
|
|
number_format($first) .
|
|
' to ' .
|
|
number_format($last) .
|
|
$this->c->rsetColor()
|
|
);
|
|
$this->startLoop = microtime(true);
|
|
|
|
// Select group, here, only once
|
|
$data = $nntp->selectGroup($groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
$data = $nntp->dataError($nntp, $groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
$binaries->scan($nntp, $groupArr, $last, $first, $process);
|
|
}
|
|
|
|
/**
|
|
* Backfill all the groups up to user specified time/date.
|
|
*
|
|
* @param object $nntp
|
|
* @param string $groupName
|
|
*
|
|
* @return void
|
|
*/
|
|
public
|
|
function backfillAllGroups($nntp, $groupName = '')
|
|
{
|
|
if (!isset($nntp)) {
|
|
$dmessage = "Not connected to usenet(backfill->backfillAllGroups).\n";
|
|
exit($this->c->error($dmessage));
|
|
}
|
|
|
|
$groups = new Groups();
|
|
|
|
if ($groupName != '') {
|
|
$grp = $groups->getByName($groupName);
|
|
if ($grp) {
|
|
$res = array($grp);
|
|
}
|
|
} else {
|
|
$res = $this->getActiveBackfill();
|
|
}
|
|
|
|
|
|
if ($res) {
|
|
$counter = 1;
|
|
$db = $this->db;
|
|
$binaries = new Binaries();
|
|
foreach ($res as $groupArr) {
|
|
if ($groupName === '') {
|
|
$dmessage = "Starting group " . $counter . ' of ' . sizeof($res);
|
|
|
|
$this->c->header . $dmessage . $this->c->rsetColor();
|
|
}
|
|
$this->backfillGroup($nntp, $db, $binaries, $groupArr, sizeof($res) - $counter);
|
|
$counter++;
|
|
}
|
|
} else {
|
|
$dmessage = "No groups specified. Ensure groups are added to newznab's database for updating.";
|
|
$this->c->primary . $dmessage . $this->c->rsetColor();
|
|
}
|
|
}
|
|
|
|
public
|
|
function backfillGroup($nntp, $db, $binaries, $groupArr, $left)
|
|
{
|
|
if (!isset($nntp)) {
|
|
$dmessage = "Not connected to usenet(backfill->backfillGroup).";
|
|
exit($this->c->error($dmessage));
|
|
}
|
|
|
|
$this->startGroup = microtime(true);
|
|
|
|
// Select group, here, only once
|
|
$data = $nntp->selectGroup($groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
$data = $nntp->dataError($nntp, $groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Get targetpost based on days target.
|
|
$targetpost = $this->daytopost($nntp, $groupArr['name'], $groupArr['backfill_target'], $data, true);
|
|
if ($targetpost < 0) {
|
|
$targetpost = round($data['first']);
|
|
}
|
|
|
|
if ($groupArr['first_record'] == 0 || $groupArr['backfill_target'] == 0) {
|
|
$dmessage = "Group ${groupArr['name']} has invalid numbers. Have you run update on it? Have you set the backfill days amount?";
|
|
|
|
$this->c->warning($dmessage);
|
|
|
|
return;
|
|
}
|
|
|
|
// Check if we are grabbing further than the server has.
|
|
if ($groupArr['first_record'] <= ($data['first'] + 50000)) {
|
|
$dmessage = "We have hit the maximum we can backfill for " . str_replace('alt.binaries', 'a.b', $groupArr['name']) . ", skipping it.";
|
|
|
|
|
|
$this->c->notice($dmessage);
|
|
//$groups = new Groups();
|
|
//$groups->disableForPost($groupArr['name']);
|
|
return;
|
|
}
|
|
|
|
// If our estimate comes back with stuff we already have, finish.
|
|
if ($targetpost >= $groupArr['first_record']) {
|
|
$dmessage = "Nothing to do, we already have the target post.";
|
|
|
|
$this->c->notice($dmessage);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->c->doecho(
|
|
'Group ' .
|
|
$data['group'] .
|
|
': server has ' .
|
|
number_format($data['first']) .
|
|
' - ' .
|
|
number_format($data['last']) .
|
|
', or ~' .
|
|
((int)
|
|
((
|
|
$this->postdate($nntp, $data['last'], false, $groupArr['name'], false, 'oldest') -
|
|
$this->postdate($nntp, $data['first'], false, $groupArr['name'], false, 'oldest')) /
|
|
86400
|
|
)) .
|
|
" days.\nLocal first = " .
|
|
number_format($groupArr['first_record']) .
|
|
' (' .
|
|
((int)
|
|
((
|
|
date('U') -
|
|
$this->postdate($nntp, $groupArr['first_record'], false, $groupArr['name'], false, 'oldest')) /
|
|
86400
|
|
)) .
|
|
' days). Backfill target of ' .
|
|
$groupArr['backfill_target'] .
|
|
' days is post ' .
|
|
$targetpost, true
|
|
);
|
|
|
|
$done = false;
|
|
// Set first and last, moving the window by maxxMssgs.
|
|
$last = $groupArr['first_record'] - 1;
|
|
// Set the initial "chunk".
|
|
$first = $last - $this->messagebuffer + 1;
|
|
|
|
// Just in case this is the last chunk we needed.
|
|
if ($targetpost > $first) {
|
|
$first = $targetpost;
|
|
}
|
|
|
|
// In case postdate doesn't get a date.
|
|
if (is_null($groupArr['first_record_postdate']) || $groupArr['first_record_postdate'] == 'NULL') {
|
|
$firstr_date = time();
|
|
} else {
|
|
$firstr_date = strtotime($groupArr['first_record_postdate']);
|
|
}
|
|
|
|
while ($done === false) {
|
|
$this->startLoop = microtime(true);
|
|
|
|
$this->c->header(
|
|
'Getting ' .
|
|
(number_format($last - $first + 1)) .
|
|
" articles from " .
|
|
str_replace('alt.binaries', 'a.b', $data['group']) .
|
|
", " . $left .
|
|
" group(s) left. (" .
|
|
(number_format($first - $targetpost)) .
|
|
" articles in queue)." .
|
|
$this->c->rsetColor()
|
|
);
|
|
|
|
flush();
|
|
$process = $this->safepartrepair ? 'update' : 'backfill';
|
|
$binaries->scan($nntp, $groupArr, $first, $last, $process);
|
|
$newdate = $this->postdate($nntp, $first, false, $groupArr['name'], true, 'oldest');
|
|
|
|
if ($newdate !== false) {
|
|
$firstr_date = $newdate;
|
|
}
|
|
|
|
$db->queryExec(sprintf('UPDATE groups SET first_record_postdate = %s, first_record = %s, last_updated = NOW() WHERE ID = %d', $this->db->from_unixtime($firstr_date), $db->escapeString($first), $groupArr['ID']));
|
|
if ($first == $targetpost) {
|
|
$done = true;
|
|
} else {
|
|
// Keep going: set new last, new first, check for last chunk.
|
|
$last = $first - 1;
|
|
$first = $last - $this->messagebuffer + 1;
|
|
if ($targetpost > $first) {
|
|
$first = $targetpost;
|
|
}
|
|
}
|
|
}
|
|
// Set group's first postdate.
|
|
$db->queryExec(sprintf('UPDATE groups SET first_record_postdate = %s, last_updated = NOW() WHERE ID = %d', $this->db->from_unixtime($firstr_date), $groupArr['ID']));
|
|
|
|
$timeGroup = number_format(microtime(true) - $this->startGroup, 2);
|
|
|
|
$this->c->primary(
|
|
'Group processed in ' .
|
|
$timeGroup .
|
|
" seconds." .
|
|
$this->c->rsetColor()
|
|
);
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns article number based on # of days.
|
|
*
|
|
* @param object $nntp
|
|
* @param string $group
|
|
* @param int $days
|
|
* @param array $data
|
|
* @param bool $debug
|
|
*
|
|
* @return string
|
|
*/
|
|
public
|
|
function daytopost($nntp, $group, $days, $data, $debug = true)
|
|
{
|
|
if (!isset($nntp)) {
|
|
$dmessage = "Not connected to usenet(backfill->daytopost).\n";
|
|
exit($this->c->error($dmessage));
|
|
}
|
|
$pddebug = false;
|
|
// Goal timestamp.
|
|
$goaldate = date('U') - (86400 * $days);
|
|
$totalnumberofarticles = $data['last'] - $data['first'];
|
|
$upperbound = $data['last'];
|
|
$lowerbound = $data['first'];
|
|
|
|
if ($data['last'] == PHP_INT_MAX) {
|
|
$dmessage = "Group data is coming back as php's max value. You should not see this since we use a patched Net_NNTP that fixes this bug.\n";
|
|
exit($this->c->info($dmessage));
|
|
}
|
|
|
|
$firstDate = $this->postdate($nntp, $data['first'], $pddebug, $group, false, 'oldest');
|
|
$lastDate = $this->postdate($nntp, $data['last'], $pddebug, $group, false, 'oldest');
|
|
|
|
if ($goaldate < $firstDate) {
|
|
$dmessage =
|
|
"Backfill target of $days day(s) is older than the first article stored on your news server.\nStarting from the first available article (" .
|
|
date('r', $firstDate) . ' or ' .
|
|
$this->daysOld($firstDate) . " days).";
|
|
|
|
$this->c->warning($dmessage);
|
|
|
|
return $data['first'];
|
|
} else if ($goaldate > $lastDate) {
|
|
$dmessage =
|
|
'Backfill target of ' .
|
|
$days .
|
|
" day(s) is newer than the last article stored on your news server.\nTo backfill this group you need to set Backfill Days to at least " .
|
|
ceil($this->daysOld($lastDate) + 1) .
|
|
' days (' .
|
|
date('r', $lastDate - 86400) .
|
|
").";
|
|
|
|
$this->c->error($dmessage);
|
|
|
|
return '';
|
|
}
|
|
|
|
|
|
$interval = floor(($upperbound - $lowerbound) * 0.5);
|
|
$templowered = '';
|
|
$dateofnextone = $lastDate;
|
|
|
|
// Match on days not timestamp to speed things up.
|
|
while ($this->daysOld($dateofnextone) < $days) {
|
|
while (($tmpDate = $this->postdate($nntp, ($upperbound - $interval), $pddebug, $group, false, 'oldest')) > $goaldate) {
|
|
$upperbound = $upperbound - $interval;
|
|
}
|
|
|
|
if (!$templowered) {
|
|
$interval = ceil(($interval / 2));
|
|
}
|
|
$dateofnextone = $this->postdate($nntp, ($upperbound - 1), $pddebug, $group, false, 'oldest');
|
|
while (!$dateofnextone) {
|
|
$dateofnextone = $this->postdate($nntp, ($upperbound - 1), $pddebug, $group, false, 'oldest');
|
|
}
|
|
}
|
|
|
|
$dmessage =
|
|
'Determined to be article: ' .
|
|
number_format($upperbound) .
|
|
' which is ' .
|
|
$this->daysOld($dateofnextone) .
|
|
' days old (' .
|
|
date('r', $dateofnextone) .
|
|
')';
|
|
|
|
|
|
$this->c->doecho($dmessage, true);
|
|
|
|
return $upperbound;
|
|
}
|
|
|
|
/**
|
|
* Convert unix time to days ago.
|
|
*
|
|
* @param int $timestamp unix time
|
|
*
|
|
* @return float
|
|
*/
|
|
private
|
|
function daysOld($timestamp)
|
|
{
|
|
return round((time() - (!is_numeric($timestamp) ? strtotime($timestamp) : $timestamp)) / 86400, 1);
|
|
}
|
|
|
|
/**
|
|
* Safe backfill using posts. Going back to a date specified by the user on the site settings.
|
|
* This does 1 group for x amount of parts until it reaches the date.
|
|
*
|
|
* @param object $nntp
|
|
* @param string $articles
|
|
*
|
|
* @return void
|
|
*/
|
|
public
|
|
function safeBackfill($nntp, $articles = '')
|
|
{
|
|
if (!isset($nntp)) {
|
|
$dmessage = "Not connected to usenet(backfill->safeBackfill).\n";
|
|
exit($this->c->error($dmessage));
|
|
}
|
|
|
|
$db = $this->db;
|
|
$groupname = $db->queryOneRow(sprintf('SELECT name FROM groups WHERE first_record_postdate BETWEEN %s AND NOW() AND backfill = 1 ORDER BY name ASC', $db->escapeString($this->safebdate)));
|
|
|
|
if (!$groupname) {
|
|
$dmessage =
|
|
'No groups to backfill, they are all at the target date ' .
|
|
$this->safebdate .
|
|
", or you have not enabled them to be backfilled in the groups page.\n";
|
|
exit($dmessage);
|
|
} else {
|
|
$this->backfillPostAllGroups($nntp, $groupname['name'], $articles, $type = '');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param object $nntp
|
|
* @param object $db
|
|
* @param object $binaries
|
|
* @param array $groupArr
|
|
* @param int $left
|
|
* @param string $articles
|
|
*
|
|
* @return void
|
|
*/
|
|
public
|
|
function backfillPostGroup($nntp, $db, $binaries, $groupArr, $left, $articles = '')
|
|
{
|
|
if (!isset($nntp)) {
|
|
$dmessage = "Not connected to usenet(backfill->backfillPostGroup).\n";
|
|
exit($this->c->error($dmessage));
|
|
}
|
|
|
|
$this->startGroup = microtime(true);
|
|
|
|
$this->c->header(
|
|
'Processing ' .
|
|
$groupArr['name'] .
|
|
$this->c->rsetColor()
|
|
);
|
|
|
|
// Select group, here, only once
|
|
$data = $nntp->selectGroup($groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
$data = $nntp->dataError($nntp, $groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Get targetpost based on days target.
|
|
$targetpost = round($groupArr['first_record'] - $articles);
|
|
if ($targetpost < 0) {
|
|
$targetpost = round($data['first']);
|
|
}
|
|
|
|
if ($groupArr['first_record'] <= 0 || $targetpost <= 0) {
|
|
$dmessage =
|
|
"You need to run update_binaries on " .
|
|
str_replace('alt.binaries', 'a.b', $data['group']) .
|
|
". Otherwise the group is dead, you must disable it.";
|
|
|
|
$this->c->error($dmessage);
|
|
|
|
return;
|
|
}
|
|
|
|
// Check if we are grabbing further than the server has.
|
|
if ($groupArr['first_record'] <= $data['first'] + $articles) {
|
|
$dmessage =
|
|
"We have hit the maximum we can backfill for " .
|
|
str_replace('alt.binaries', 'a.b', $groupArr['name']) .
|
|
", skipping it.";
|
|
|
|
$this->c->notice($dmessage);
|
|
|
|
//$groups = new Groups();
|
|
//$groups->disableForPost($groupArr['name']);
|
|
return;
|
|
}
|
|
|
|
// If our estimate comes back with stuff we already have, finish.
|
|
if ($targetpost >= $groupArr['first_record']) {
|
|
$dmessage = "Nothing to do, we already have the target post.";
|
|
|
|
$this->c->notice($dmessage);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->c->primary(
|
|
'Group ' . $data['group'] .
|
|
"'s oldest article is " .
|
|
number_format($data['first']) .
|
|
', newest is ' .
|
|
number_format($data['last']) .
|
|
'. The groups retention is: ' .
|
|
((int)
|
|
((
|
|
$this->postdate($nntp, $data['last'], false, $groupArr['name'], false, 'oldest') -
|
|
$this->postdate($nntp, $data['first'], false, $groupArr['name'], false, 'oldest')) /
|
|
86400
|
|
)) .
|
|
" days.\nOur oldest article is: " .
|
|
number_format($groupArr['first_record']) .
|
|
' which is (' .
|
|
((int)
|
|
((
|
|
date('U') -
|
|
$this->postdate($nntp, $groupArr['first_record'], false, $groupArr['name'], false, 'oldest')) /
|
|
86400
|
|
)) .
|
|
' days old). Our backfill target is article ' .
|
|
number_format($targetpost) .
|
|
' which is (' .
|
|
((int)
|
|
((
|
|
date('U') -
|
|
$this->postdate($nntp, $targetpost, false, $groupArr['name'], false, 'oldest')) /
|
|
86400
|
|
)) .
|
|
"\n days old)." .
|
|
$this->c->rsetColor()
|
|
);
|
|
|
|
|
|
// Calculate total number of parts.
|
|
$done = false;
|
|
// Set first and last, moving the window by maxxMssgs.
|
|
$last = $groupArr['first_record'] - 1;
|
|
// Set the initial "chunk".
|
|
$first = $last - $this->messagebuffer + 1;
|
|
// Just in case this is the last chunk we needed.
|
|
if ($targetpost > $first) {
|
|
$first = $targetpost;
|
|
}
|
|
|
|
// In case postdate doesn't get a date.
|
|
if (is_null($groupArr['first_record_postdate']) || $groupArr['first_record_postdate'] == 'NULL') {
|
|
$firstr_date = time();
|
|
} else {
|
|
$firstr_date = strtotime($groupArr['first_record_postdate']);
|
|
}
|
|
|
|
while ($done === false) {
|
|
$this->startLoop = microtime(true);
|
|
|
|
$this->c->header(
|
|
"\nGetting " .
|
|
($last - $first + 1) .
|
|
" articles from " .
|
|
str_replace('alt.binaries', 'a.b', str_replace('alt.binaries', 'a.b', $data['group'])) .
|
|
", " .
|
|
$left .
|
|
" group(s) left. (" .
|
|
(number_format($first - $targetpost)) .
|
|
" articles in queue)" .
|
|
$this->c->rsetColor()
|
|
);
|
|
|
|
flush();
|
|
$process = $this->safepartrepair ? 'update' : 'backfill';
|
|
$binaries->scan($nntp, $groupArr, $first, $last, $process);
|
|
$newdate = $this->postdate($nntp, $first, false, $groupArr['name'], true, 'oldest');
|
|
if ($newdate !== false) {
|
|
$firstr_date = $newdate;
|
|
}
|
|
|
|
$db->queryExec(sprintf('UPDATE groups SET first_record_postdate = %s, first_record = %s, last_updated = NOW() WHERE ID = %d', $this->db->from_unixtime($firstr_date), $db->escapeString($first), $groupArr['ID']));
|
|
if ($first == $targetpost) {
|
|
$done = true;
|
|
} else {
|
|
// Keep going: set new last, new first, check for last chunk.
|
|
$last = $first - 1;
|
|
$first = $last - $this->messagebuffer + 1;
|
|
if ($targetpost > $first) {
|
|
$first = $targetpost;
|
|
}
|
|
}
|
|
}
|
|
// Set group's first postdate.
|
|
$db->queryExec(sprintf('UPDATE groups SET first_record_postdate = %s, last_updated = NOW() WHERE ID = %d', $this->db->from_unixtime($firstr_date), $groupArr['ID']));
|
|
|
|
$timeGroup = number_format(microtime(true) - $this->startGroup, 2);
|
|
|
|
|
|
$this->c->header(
|
|
$data['group'] .
|
|
' processed in ' .
|
|
$timeGroup .
|
|
" seconds." .
|
|
$this->c->rsetColor()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Download new headers for a single group.
|
|
*
|
|
* @param array $groupArr Array of MySQL results for a single group.
|
|
* @param object $nntp Instance of class NNTP
|
|
*
|
|
* @return void
|
|
*/
|
|
public
|
|
function updateGroup($groupArr, $nntp)
|
|
{
|
|
if (!isset($nntp)) {
|
|
$message = "Not connected to usenet(binaries->updateGroup).";
|
|
exit($this->c->error($message));
|
|
}
|
|
|
|
|
|
$this->startGroup = microtime(true);
|
|
$this->c->primary('Processing ' . str_replace('alt.binaries', 'a.b', $groupArr['name']));
|
|
$binaries = new Binaries();
|
|
|
|
|
|
// Select the group, here, needed for processing the group
|
|
$data = $nntp->selectGroup($groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
$data = $nntp->dataError($nntp, $groupArr['name']);
|
|
if ($nntp->isError($data)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
// Attempt to repair any missing parts before grabbing new ones.
|
|
if ($groupArr['last_record'] != 0) {
|
|
if ($this->DoPartRepair) {
|
|
$this->c->primary("Part repair enabled. Checking for missing parts.");
|
|
$this->partRepair($nntp, $groupArr);
|
|
} else {
|
|
$this->c->primary("Part repair disabled by user.");
|
|
}
|
|
}
|
|
|
|
// Get first and last part numbers from newsgroup.
|
|
$db = $this->db;
|
|
|
|
if ($groupArr['last_record'] == 0) {
|
|
// For new newsgroups - determine here how far you want to go back.
|
|
if ($this->NewGroupScanByDays) {
|
|
$first = $this->daytopost($this->NewGroupDaysToScan, $data);
|
|
if ($first == '') {
|
|
$this->c->warning("Skipping group: {$groupArr['name']}");
|
|
|
|
return;
|
|
}
|
|
} else {
|
|
if ($data['first'] > ($data['last'] - ($this->NewGroupMsgsToScan + $this->messagebuffer))) {
|
|
$first = $data['first'];
|
|
} else {
|
|
$first = $data['last'] - ($this->NewGroupMsgsToScan + $this->messagebuffer);
|
|
}
|
|
}
|
|
|
|
$left = $this->messagebuffer;
|
|
$last = $grouplast = $data['last'] - $left;
|
|
} else {
|
|
$first = $groupArr['last_record'];
|
|
|
|
// Leave 50%+ of the new articles on the server for next run (allow server enough time to actually make parts available).
|
|
$newcount = $data['last'] - $first;
|
|
$left = 0;
|
|
if ($newcount > $this->messagebuffer) {
|
|
// Drop the remaining plus $this->messagebuffer, pick them up on next run
|
|
if ($newcount < (2 * $this->messagebuffer)) {
|
|
$left = ((int)($newcount / 2));
|
|
$last = $grouplast = ($data['last'] - $left);
|
|
} else {
|
|
$remainingcount = $newcount % $this->messagebuffer;
|
|
$left = $remainingcount + $this->messagebuffer;
|
|
$last = $grouplast = ($data['last'] - $left);
|
|
}
|
|
} else {
|
|
$left = ((int)($newcount / 2));
|
|
$last = $grouplast = ($data['last'] - $left);
|
|
}
|
|
}
|
|
|
|
// Generate postdate for first record, for those that upgraded.
|
|
if (is_null($groupArr['first_record_postdate']) && $groupArr['first_record'] != '0') {
|
|
$newdate = $this->postdate($groupArr['first_record'], $data);
|
|
if ($newdate !== false) {
|
|
$first_record_postdate = $newdate;
|
|
} else {
|
|
$first_record_postdate = time();
|
|
}
|
|
|
|
$groupArr['first_record_postdate'] = $first_record_postdate;
|
|
|
|
$db->queryExec(sprintf('UPDATE groups SET first_record_postdate = %s WHERE ID = %d', $this->db->from_unixtime($first_record_postdate), $groupArr['ID']));
|
|
}
|
|
|
|
// Defaults for post record first/last postdate
|
|
if (is_null($groupArr['first_record_postdate'])) {
|
|
$first_record_postdate = time();
|
|
} else {
|
|
$first_record_postdate = strtotime($groupArr['first_record_postdate']);
|
|
}
|
|
|
|
if (is_null($groupArr['last_record_postdate'])) {
|
|
$last_record_postdate = time();
|
|
} else {
|
|
$last_record_postdate = strtotime($groupArr['last_record_postdate']);
|
|
}
|
|
|
|
|
|
// Calculate total number of parts.
|
|
$total = $grouplast - $first;
|
|
$realtotal = $data['last'] - $first;
|
|
|
|
// If total is bigger than 0 it means we have new parts in the newsgroup.
|
|
if ($total > 0) {
|
|
if ($groupArr['last_record'] == 0) {
|
|
$this->c->primary(
|
|
'New group ' .
|
|
$data['group'] .
|
|
' starting with ' .
|
|
(($this->NewGroupScanByDays) ? $this->NewGroupDaysToScan
|
|
. ' days' : number_format($this->NewGroupMsgsToScan) .
|
|
' messages'
|
|
) .
|
|
" worth. Leaving " .
|
|
number_format($left) .
|
|
" for next pass.\nServer oldest: " .
|
|
number_format($data['first']) .
|
|
' Server newest: ' .
|
|
number_format($data['last']) .
|
|
' Local newest: ' .
|
|
number_format($groupArr['last_record'])
|
|
);
|
|
} else {
|
|
$this->c->primary(
|
|
'Group ' .
|
|
$data['group'] .
|
|
' has ' .
|
|
number_format($realtotal) .
|
|
" new articles. Leaving " .
|
|
number_format($left) .
|
|
" for next pass.\nServer oldest: " .
|
|
number_format($data['first']) . ' Server newest: ' .
|
|
number_format($data['last']) .
|
|
' Local newest: ' .
|
|
number_format($groupArr['last_record'])
|
|
);
|
|
}
|
|
|
|
$done = false;
|
|
// Get all the parts (in portions of $this->messagebuffer to not use too much memory).
|
|
while ($done === false) {
|
|
$this->startLoop = microtime(true);
|
|
|
|
if ($total > $this->messagebuffer) {
|
|
if ($first + $this->messagebuffer > $grouplast) {
|
|
$last = $grouplast;
|
|
} else {
|
|
$last = $first + $this->messagebuffer;
|
|
}
|
|
}
|
|
$first++;
|
|
$this->c->header(
|
|
"Getting " .
|
|
number_format($last - $first + 1) .
|
|
' articles (' . number_format($first) .
|
|
' to ' .
|
|
number_format($last) .
|
|
') from ' .
|
|
str_replace('alt.binaries', 'a.b', $data['group']) .
|
|
" - (" .
|
|
number_format($grouplast - $last) .
|
|
" articles in queue)."
|
|
);
|
|
flush();
|
|
|
|
// Get article headers from newsgroup. Let scan deal with nntp connection, else compression fails after first grab
|
|
$scanSummary = $binaries->scan($nntp, $groupArr, $first, $last);
|
|
|
|
// Scan failed - skip group.
|
|
if ($scanSummary == false) {
|
|
return;
|
|
}
|
|
|
|
// If new group, update first record & postdate
|
|
if (is_null($groupArr['first_record_postdate']) && $groupArr['first_record'] == '0') {
|
|
$groupArr['first_record'] = $scanSummary['firstArticleNumber'];
|
|
|
|
if (isset($scanSummary['firstArticleDate'])) {
|
|
$first_record_postdate = strtotime($scanSummary['firstArticleDate']);
|
|
}
|
|
|
|
$groupArr['first_record_postdate'] = $first_record_postdate;
|
|
|
|
$db->queryExec(sprintf('UPDATE groups SET first_record = %s, first_record_postdate = %s WHERE ID = %d', $scanSummary['firstArticleNumber'], $this->db->from_unixtime($db->escapeString($first_record_postdate)), $groupArr['ID']));
|
|
}
|
|
|
|
if (isset($scanSummary['lastArticleDate'])) {
|
|
$last_record_postdate = strtotime($scanSummary['lastArticleDate']);
|
|
}
|
|
|
|
$db->queryExec(sprintf('UPDATE groups SET last_record = %s, last_record_postdate = %s, last_updated = NOW() WHERE ID = %d', $db->escapeString($scanSummary['lastArticleNumber']), $this->db->from_unixtime($last_record_postdate), $groupArr['ID']));
|
|
|
|
if ($last == $grouplast) {
|
|
$done = true;
|
|
} else {
|
|
$first = $last;
|
|
}
|
|
}
|
|
$timeGroup = number_format(microtime(true) - $this->startGroup, 2);
|
|
$this->c->primary($data['group'] . ' processed in ' . $timeGroup . " seconds.");
|
|
} else {
|
|
$this->c->primary(
|
|
'No new articles for ' .
|
|
$data['group'] .
|
|
' (first ' .
|
|
number_format($first) .
|
|
' last ' .
|
|
number_format($last) .
|
|
' grouplast ' .
|
|
number_format($groupArr['last_record']) .
|
|
' total ' . number_format($total) .
|
|
")\n" .
|
|
"Server oldest: " .
|
|
number_format($data['first']) .
|
|
' Server newest: ' .
|
|
number_format($data['last']) .
|
|
' Local newest: ' .
|
|
number_format($groupArr['last_record'])
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Attempt to get missing headers.
|
|
*
|
|
* @param $nntp Instance of class NNTP.
|
|
* @param $groupArr The info for this group from mysql.
|
|
*
|
|
* @return void
|
|
*/
|
|
public
|
|
function partRepair($nntp, $groupArr)
|
|
{
|
|
if (!isset($nntp)) {
|
|
$dmessage = "Not connected to usenet(functions->partRepair).";
|
|
exit($this->c->error("Not connected to usenet(functions->partRepair)."));
|
|
}
|
|
|
|
// Get all parts in partrepair table.
|
|
$db = $this->db;
|
|
|
|
// Check that tables exist, create if they do not
|
|
$group['prname'] = 'partrepair';
|
|
|
|
$missingParts = $db->query(sprintf('SELECT * FROM ' . $group['prname'] . ' WHERE groupID = %d AND attempts < 5 ORDER BY numberID ASC LIMIT %d', $groupArr['ID'], $this->partrepairlimit));
|
|
$partsRepaired = $partsFailed = 0;
|
|
|
|
if (sizeof($missingParts) > 0) {
|
|
$this->consoleTools->overWritePrimary(
|
|
'Attempting to repair ' .
|
|
number_format(sizeof($missingParts)) .
|
|
" parts."
|
|
);
|
|
|
|
// Loop through each part to group into continuous ranges with a maximum range of messagebuffer/4.
|
|
$ranges = array();
|
|
$partlist = array();
|
|
$firstpart = $lastnum = $missingParts[0]['numberID'];
|
|
foreach ($missingParts as $part) {
|
|
if (($part['numberID'] - $firstpart) > ($this->messagebuffer / 4)) {
|
|
$ranges[] = array('partfrom' => $firstpart, 'partto' => $lastnum, 'partlist' => $partlist);
|
|
$firstpart = $part['numberID'];
|
|
$partlist = array();
|
|
}
|
|
$partlist[] = $part['numberID'];
|
|
$lastnum = $part['numberID'];
|
|
}
|
|
$ranges[] = array('partfrom' => $firstpart, 'partto' => $lastnum, 'partlist' => $partlist);
|
|
|
|
$num_attempted = 0;
|
|
|
|
// Download missing parts in ranges.
|
|
foreach ($ranges as $range) {
|
|
$this->startLoop = microtime(true);
|
|
|
|
$partfrom = $range['partfrom'];
|
|
$partto = $range['partto'];
|
|
$partlist = $range['partlist'];
|
|
$count = sizeof($range['partlist']);
|
|
|
|
$num_attempted += $count;
|
|
$this->consoleTools->overWritePrimary("Attempting repair: " . $this->consoleTools->percentString2($num_attempted - $count + 1, $num_attempted, sizeof($missingParts)) . ': ' . $partfrom . ' to ' . $partto);
|
|
|
|
// Get article from newsgroup.
|
|
$binaries = new Binaries();
|
|
$binaries->scan($nntp, $groupArr, $partfrom, $partto, 'update');
|
|
}
|
|
|
|
// Calculate parts repaired
|
|
$sql = sprintf('SELECT COUNT(ID) AS num FROM ' . $group['prname'] . ' WHERE groupID=%d AND numberID <= %d', $groupArr['ID'], $missingParts[sizeof($missingParts) - 1]['numberID']);
|
|
$result = $db->queryOneRow($sql);
|
|
if (isset($result['num'])) {
|
|
$partsRepaired = (sizeof($missingParts)) - $result['num'];
|
|
}
|
|
|
|
// Update attempts on remaining parts for active group
|
|
if (isset($missingParts[sizeof($missingParts) - 1]['ID'])) {
|
|
$sql = sprintf("UPDATE ${group['prname']} SET attempts=attempts+1 WHERE groupID=%d AND numberID <= %d", $groupArr['ID'], $missingParts[sizeof($missingParts) - 1]['numberID']);
|
|
$result = $db->queryExec($sql);
|
|
if ($result) {
|
|
$partsFailed = $result->rowCount();
|
|
}
|
|
}
|
|
|
|
$this->c->primary(
|
|
"\n" .
|
|
number_format($partsRepaired) .
|
|
" parts repaired."
|
|
);
|
|
}
|
|
|
|
// Remove articles that we cant fetch after 5 attempts.
|
|
$db->queryExec(sprintf('DELETE FROM ' . $group['prname'] . ' WHERE attempts >= 5 AND groupID = %d', $groupArr['ID']));
|
|
}
|
|
//end of testing
|
|
} |