/** * resets totals of a transfer * * @param $transfer name of the transfer * @param $delete boolean if to delete meta-file * @return array */ function resetTransferTotals($transfer, $delete = false) { global $cfg, $db, $transfers; $msgs = array(); $tid = getTransferHash($transfer); $client = getTransferClient($transfer); // delete meta-file if ($delete) { $ch = ClientHandler::getInstance($client); $ch->delete($transfer); if (count($ch->messages) > 0) { $msgs = array_merge($msgs, $ch->messages); } } else { // reset in stat-file $sf = new StatFile($transfer, getOwner($transfer)); $sf->uptotal = 0; $sf->downtotal = 0; $sf->write(); if ($client == "vuzerpc") { require_once "inc/functions/functions.rpc.vuze.php"; vuzeResetUpload($tid); } } // reset in db $uid = (int) getTransferOwnerID($transfer); $sql = "UPDATE tf_transfer_totals SET uptotal=0 WHERE tid = " . $db->qstr($tid) . " AND uid IN (0,{$uid})"; $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } // set transfers-cache cacheTransfersSet(); return $msgs; }
/** * _maintenanceDatabase */ function _maintenanceDatabase() { global $cfg, $db; // output $this->_outputMessage("database-maintenance...\n"); /* tf_transfers */ $this->_countProblems = 0; $this->_countFixed = 0; // output $this->_outputMessage("table-maintenance : tf_transfers\n"); // running-flag $sql = "SELECT transfer FROM tf_transfers WHERE running = '1'"; $recordset = $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } $rc = $recordset->RecordCount(); if ($rc > 0) { while (list($tname) = $recordset->FetchRow()) { if (!isTransferRunning($tname)) { $this->_countProblems++; // t is not running, reset running-flag $this->_outputMessage("reset of running-flag for transfer which is not running : " . $tname . "\n"); $sql = "UPDATE tf_transfers SET running = '0' WHERE transfer = " . $db->qstr($tname); $db->Execute($sql); $this->_countFixed++; // output $this->_outputMessage("done.\n"); } } } // empty hash $sql = "SELECT transfer FROM tf_transfers WHERE hash = ''"; $recordset = $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } $rc = $recordset->RecordCount(); if ($rc > 0) { $this->_countProblems += $rc; while (list($tname) = $recordset->FetchRow()) { // t has no hash, update $this->_outputMessage("updating transfer which has empty hash : " . $tname . "\n"); // get hash $thash = getTransferHash($tname); // update if (!empty($thash)) { $sql = "UPDATE tf_transfers SET hash = " . $db->qstr($thash) . " WHERE transfer = " . $db->qstr($tname); $db->Execute($sql); $this->_countFixed++; // output $this->_outputMessage("done.\n"); } } } // empty datapath $sql = "SELECT transfer FROM tf_transfers WHERE datapath = ''"; $recordset = $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } $rc = $recordset->RecordCount(); if ($rc > 0) { $this->_countProblems += $rc; while (list($tname) = $recordset->FetchRow()) { // t has no datapath, update $this->_outputMessage("updating transfer which has empty datapath : " . $tname . "\n"); // get datapath $tDatapath = getTransferDatapath($tname); // update if ($tDatapath != "") { $sql = "UPDATE tf_transfers SET datapath = " . $db->qstr($tDatapath) . " WHERE transfer = " . $db->qstr($tname); $db->Execute($sql); $this->_countFixed++; // output $this->_outputMessage("done.\n"); } else { // output $this->_outputMessage("cannot get datapath for " . $tname . ".\n"); } } } // output + log if ($this->_countProblems == 0) { // output $this->_outputMessage("no problems found.\n"); } else { // DEBUG : log $msg = "found and fixed problems in tf_transfers : " . $this->_countFixed . "/" . $this->_countProblems; if ($cfg['debuglevel'] > 0) { AuditAction($cfg["constants"]["debug"], "database-maintenance : table-maintenance : " . $msg); } // output $this->_outputMessage($msg . "\n"); } /* tf_transfer_totals */ $this->_countProblems = 0; $this->_countFixed = 0; // output $this->_outputMessage("table-maintenance : tf_transfer_totals\n"); $this->_countProblems = $db->GetOne("SELECT COUNT(*) FROM tf_transfer_totals WHERE tid = ''"); if ($this->_countProblems !== false && $this->_countProblems > 0) { // output $this->_outputMessage("found " . $this->_countProblems . " invalid entries, deleting...\n"); $sql = "DELETE FROM tf_transfer_totals WHERE tid = ''"; $result = $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } $this->_countFixed = $db->Affected_Rows(); // output $this->_outputMessage("done.\n"); $rCount = $this->_countFixed !== false ? $this->_countFixed : $this->_countProblems; // DEBUG : log $msg = "found and removed invalid totals-entries from tf_transfer_totals : " . $rCount . "/" . $this->_countProblems; if ($cfg['debuglevel'] > 0) { AuditAction($cfg["constants"]["debug"], "database-maintenance : table-maintenance : " . $msg); } // output $this->_outputMessage($msg . "\n"); } else { // output $this->_outputMessage("no problems found.\n"); } // null uid $sql = "SELECT tid FROM tf_transfer_totals WHERE uid = 0"; $recordset = $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } $rc = $recordset->RecordCount(); if ($rc > 0) { $this->_countProblems += $rc; while (list($tid) = $recordset->FetchRow()) { // get uid $tname = getTransferFromHash($tid); if (!empty($tname)) { $uid = (int) getTransferOwnerID($tname); } else { $uid = 0; } // t has no uid, update if ($uid > 0) { $this->_outputMessage("updating tf_transfer_totals which has empty uid : " . $tname . "\n"); $sql = "UPDATE tf_transfer_totals SET uid = {$uid} WHERE tid = " . $db->qstr($tid) . " AND uid=0"; $db->Execute($sql); //if duplicates, delete old uid=0 $sql = "DELETE FROM tf_transfer_totals WHERE tid = " . $db->qstr($tid) . " AND uid=0"; $db->Execute($sql); $this->_countFixed++; // output $this->_outputMessage("done.\n"); } elseif (!empty($tname)) { // output $this->_outputMessage("cannot get uid for " . $tname . ".\n"); } /* else { // old transfers (for global stats) $this->_outputMessage("cannot get uid for hash ".$tid.".\n"); } */ } } //xfer delete TB day values $sql = "SELECT user_id, date FROM tf_xfer WHERE download > '1000000000000' or upload > '1000000000000'"; $recordset = $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } $rc = $recordset->RecordCount(); if ($rc > 0) { $this->_outputMessage("updating xfer which has TeraBytes day count\n"); $this->_countProblems += $rc; while (list($username, $date) = $recordset->FetchRow()) { //if duplicates, delete old uid=0 $sql = "DELETE FROM tf_xfer WHERE user_id = " . $db->qstr($username) . " AND date=" . $db->qstr($date); $db->Execute($sql); $this->_countFixed++; } $this->_outputMessage("done (" . $this->_countFixed . ").\n"); } // prune db $this->_maintenanceDatabasePrune(); /* done */ $this->_outputMessage("database-maintenance done.\n"); }
/** * get Owner (username) * * @param $transfer * @return string */ function getOwner($transfer) { global $cfg, $db, $transfers; if (isset($transfers['owner'][$transfer])) { return $transfers['owner'][$transfer]; } else { $uid = (int) getTransferOwnerID($transfer); if ($uid > 0) { //fast method return GetUsername($uid); } elseif (isHash($transfer)) { $uid = $db->GetOne("SELECT uid FROM tf_transfer_totals WHERE tid=" . $db->qstr($transfer) . " ORDER BY created DESC"); if ($db->ErrorNo() != 0) { dbError($sql); } $transfers['owner'][$transfer] = GetUsername($uid); } else { //slower, needed for old transfers (before TFNG) // Check log to see what user has a history with this file $transfers['owner'][$transfer] = $db->GetOne("SELECT user_id FROM tf_log WHERE file=" . $db->qstr($transfer) . " AND (action=" . $db->qstr($cfg["constants"]["file_upload"]) . " OR action=" . $db->qstr($cfg["constants"]["url_upload"]) . " OR action=" . $db->qstr($cfg["constants"]["reset_owner"]) . ") ORDER BY time DESC"); return $transfers['owner'][$transfer] != "" ? $transfers['owner'][$transfer] : resetOwner($transfer); // try and get the owner from the stat file; } } }
function updateStatFiles($bShowMissing = false) { global $cfg, $db, $client; $rpc = Transmission::getInstance($cfg); // check if running and get all session variables in cache if (!$rpc->session_get()) { echo "unable to connect to transmission-daemon\n"; return; } $tfs = $rpc->torrent_get_tf(); if (empty($tfs)) { echo "no loaded torrents\n"; return; } $sql = "SELECT hash, transfer, sharekill FROM tf_transfers WHERE type='torrent' AND client = 'transmissionrpc'"; $hashes = array("''"); foreach ($tfs as $hash => $t) { $hashes[] = "'" . strtolower($hash) . "'"; } $sql .= " AND hash IN (" . implode(',', $hashes) . ")"; $recordset = $db->Execute($sql); $hashes = array(); $sharekills = array(); while (list($hash, $transfer, $sharekill) = $recordset->FetchRow()) { $hash = strtolower($hash); $hashes[$hash] = $transfer; $sharekills[$hash] = $sharekill; } $max_ul = 1024.0 * $cfg['max_upload_rate']; $max_dl = 1024.0 * $cfg['max_download_rate']; //SHAREKILLS Checks $nbUpdate = 0; foreach ($tfs as $hash => $t) { if (!isset($sharekills[$hash])) { continue; } if (($t['status'] == 8 || $t['status'] == 9) && $t['sharing'] > $sharekills[$hash]) { $transfer = $hashes[$hash]; $nbUpdate++; if (stopTransmissionTransferCron($hash)) { AuditAction($cfg["constants"]["debug"], $client . ": stop error {$transfer}."); } else { AuditAction($cfg["constants"]["stop_transfer"], $this->client . "-stat. : sharekill stopped {$transfer}"); // flag the transfer as stopped (in db) stopTransferSettings($transfer); } } } echo " stopped {$nbUpdate} torrents.\n"; $nbUpdate = 0; $missing = array(); foreach ($tfs as $hash => $t) { if (!isset($hashes[$hash])) { if ($bShowMissing) { $missing[$t['rpcid']] = $t['name']; } continue; } $transfer = $hashes[$hash]; //file_put_contents($cfg["path"].'.Transmission/'."updateStatFiles4.log",serialize($t)); $sf = new StatFile($transfer); $sf->running = $t['running']; if (empty($sf->transferowner)) { $uid = getTransferOwnerID($hash); if ($uid > 0) { $sf->transferowner = GetUsername($uid); echo "transfer '{$transfer}' owner fixed to " . $sf->transferowner . " \n"; $sf->write(); } } if ($sf->running) { $sharebase = (int) $sharekills[$hash]; //$sharekill = (int) round(floatval($t['seedRatioLimit']) * 100); if ($sharebase > 0 && (int) $sf->seedlimit == 0) { AuditAction($cfg["constants"]["debug"], $client . ": changed empty .stat sharekill " . $sf->seedlimit . " to {$sharebase} (from db), {$transfer}."); $sf->seedlimit = $sharebase; } $max_ul = max($t['urate'], $max_ul); $max_dl = max($t['drate'], $max_dl); $max_share = max($sharebase, $sharekill); if ($t['eta'] > 0 || $t['eta'] < -1) { $sf->time_left = convertTimeText($t['eta']); } $sf->percent_done = $t['percentDone']; $sf->sharing = round($t['sharing'], 1); if ($t['status'] != 9 && $t['status'] != 5) { $sf->peers = $t['peers']; $sf->seeds = $t['seeds']; } if ($t['seeds'] >= 0) { $sf->seeds = $t['seeds']; } if ($t['peers'] >= 0) { $sf->peers = $t['peers']; } if ((double) $t['speedDown'] >= 0.0) { $sf->down_speed = formatBytesTokBMBGBTB($t['speedDown']) . "/s"; } if ((double) $t['speedUp'] >= 0.0) { $sf->up_speed = formatBytesTokBMBGBTB($t['speedUp']) . "/s"; } if ($t['status'] == 8) { $sf->percent_done = 100 + $t['sharing']; $sf->down_speed = " "; if (trim($sf->up_speed) == '') { $sf->up_speed = " "; } } if ($t['status'] == 9) { $sf->percent_done = 100 + $t['sharing']; $sf->up_speed = " "; $sf->down_speed = " "; } } else { //Stopped or finished... $sf->down_speed = ""; $sf->up_speed = ""; $sf->peers = ""; $sf->time_left = "0"; if ($t['eta'] < -1) { $sf->time_left = "Done in " . convertTimeText($t['eta']); } elseif ($sf->percent_done >= 100 && strpos($sf->time_left, 'Done') === false && strpos($sf->time_left, 'Finished') === false) { $sf->percent_done = 100; $sf->time_left = "Done!"; } if ($sf->sharing == 0) { $sf->sharing = round($t['sharing'], 1); } if (is_file($cfg["transfer_file_path"] . '/' . $transfer . ".pid")) { unlink($cfg["transfer_file_path"] . '/' . $transfer . ".pid"); } //if ($sf->percent_done < 100 && $sf->percent_done > 0) // $sf->percent_done = 0 - $sf->percent_done; } $sf->downtotal = $t['downTotal']; $sf->uptotal = $t['upTotal']; if ($sf->size == 0) { $sf->size = $t['size']; } if ($sf->seeds = -1) { } $sf->seeds = ''; if ($sf->write()) { $nbUpdate++; } } $nb = count($tfs); echo " updated {$nbUpdate}/{$nb} stat files.\n"; //fix globall sharekill to maximum of torrents sharekill, other torrent with lower sharekill will be stopped by this cron /* if (isset($max_share)) { $sharekill = getTransmissionShareKill(); if ($max_share > $sharekill) { //set vuze global sharekill to max sharekill value $rpc->session_set( array('seedRatioLimit' => round($max_share / 100, 2)) ); if ($cfg['debuglevel'] > 0) { $msg = $client.": changed vuze global sharekill from $sharekill to $max_share."; AuditAction($cfg["constants"]["debug"], $msg); echo $msg."\n"; } } } if ($max_ul > 0) { $vzmaxul = getTransmissionSpeedLimitUpload(); if ($cfg['max_upload_rate'] > 0 && $max_ul > 0) { $max_ul = min($max_ul, 1024.0 * $cfg['max_upload_rate']); } if ($vzmaxul != $max_ul) { $max_ul = $max_ul / 1024; $rpc->session_set( array('speed-limit-up' => $max_ul) ); if ($cfg['debuglevel'] > 0) { $msg = $client.": tranmission global speed-limit-up from $vzmaxul to $max_ul."; AuditAction($cfg["constants"]["debug"], $msg); echo $msg."\n"; } } } */ if ($bShowMissing) { return $missing; } }