mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
revamp torrent log uploading
This commit is contained in:
@@ -2,94 +2,44 @@
|
|||||||
|
|
||||||
namespace Gazelle\Json;
|
namespace Gazelle\Json;
|
||||||
|
|
||||||
use Gazelle\File\RipLog;
|
|
||||||
use Gazelle\File\RipLogHTML;
|
|
||||||
use Gazelle\Logfile;
|
|
||||||
use Gazelle\LogfileSummary;
|
|
||||||
use OrpheusNET\Logchecker\Logchecker;
|
use OrpheusNET\Logchecker\Logchecker;
|
||||||
|
|
||||||
class AddLog extends \Gazelle\Json {
|
class AddLog extends \Gazelle\Json {
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected \Gazelle\Torrent $torrent,
|
protected \Gazelle\Torrent $torrent,
|
||||||
protected \Gazelle\User $user,
|
protected \Gazelle\User $user,
|
||||||
protected array $files,
|
protected \Gazelle\Manager\TorrentLog $torrentLogManager,
|
||||||
|
protected \Gazelle\LogfileSummary $logfileSummary,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public function payload(): ?array {
|
public function payload(): ?array {
|
||||||
$logfiles = [];
|
|
||||||
if ($this->user->id() !== $this->torrent->uploaderId() && !$this->user->permitted('admin_add_log')) {
|
if ($this->user->id() !== $this->torrent->uploaderId() && !$this->user->permitted('admin_add_log')) {
|
||||||
$this->failure('Not the torrent owner or moderator');
|
$this->failure('Not the torrent owner or moderator');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$logfileSummary = new LogfileSummary;
|
|
||||||
$ripFiler = new RipLog;
|
|
||||||
$htmlFiler = new RipLogHTML;
|
|
||||||
|
|
||||||
$torrentId = $this->torrent->id();
|
|
||||||
$logSummaries = [];
|
$logSummaries = [];
|
||||||
for ($i = 0, $total = count($this->files['name']); $i < $total; $i++) {
|
$checkerVersion = Logchecker::getLogcheckerVersion();
|
||||||
if (!$this->files['size'][$i]) {
|
foreach($this->logfileSummary->all() as $logfile) {
|
||||||
continue;
|
$this->torrentLogManager->create($this->torrent, $logfile, $checkerVersion);
|
||||||
}
|
|
||||||
$logfile = new Logfile(
|
|
||||||
$this->files['tmp_name'][$i],
|
|
||||||
$this->files['name'][$i]
|
|
||||||
);
|
|
||||||
$logfiles[] = $logfile;
|
|
||||||
$logfileSummary->add($logfile);
|
|
||||||
|
|
||||||
self::$db->prepared_query('
|
|
||||||
INSERT INTO torrents_logs
|
|
||||||
(TorrentID, Score, `Checksum`, FileName, Ripper, RipperVersion, `Language`, ChecksumState, LogcheckerVersion, Details)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
', $torrentId, $logfile->score(), $logfile->checksumStatus(), $logfile->filename(), $logfile->ripper(),
|
|
||||||
$logfile->ripperVersion(), $logfile->language(), $logfile->checksumState(),
|
|
||||||
Logchecker::getLogcheckerVersion(), $logfile->detailsAsString()
|
|
||||||
);
|
|
||||||
$logId = self::$db->inserted_id();
|
|
||||||
$ripFiler->put($logfile->filepath(), [$torrentId, $logId]);
|
|
||||||
$htmlFiler->put($logfile->text(), [$torrentId, $logId]);
|
|
||||||
|
|
||||||
$logSummaries[] = [
|
$logSummaries[] = [
|
||||||
'score' => $logfile->score(),
|
'score' => $logfile->score(),
|
||||||
'checksum' => $logfile->checksumState(),
|
'checksum' => $logfile->checksumState(),
|
||||||
'ripper' => $logfile->ripper(),
|
'ripper' => $logfile->ripper(),
|
||||||
'ripperVersion' => $logfile->ripperVersion(),
|
'ripperVersion' => $logfile->ripperVersion(),
|
||||||
'language' => $logfile->language(),
|
'language' => $logfile->language(),
|
||||||
'details' => $logfile->detailsAsString()
|
'details' => $logfile->detailsAsString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$this->torrent->updateLogScore($logfileSummary);
|
$this->torrent->modifyLogscore();
|
||||||
|
$this->torrent->flush();
|
||||||
[$score, $checksum] = self::$db->row("
|
|
||||||
SELECT min(CASE WHEN Adjusted = '1' THEN AdjustedScore ELSE Score END) AS Score,
|
|
||||||
min(CASE WHEN Adjusted = '1' THEN AdjustedChecksum ELSE Checksum END) AS Checksum
|
|
||||||
FROM torrents_logs
|
|
||||||
WHERE TorrentID = ?
|
|
||||||
GROUP BY TorrentID
|
|
||||||
", $torrentId
|
|
||||||
);
|
|
||||||
|
|
||||||
self::$db->prepared_query(
|
|
||||||
'UPDATE torrents SET LogScore = ?, LogChecksum = ?, HasLogDB = ? WHERE ID = ?',
|
|
||||||
$score, $checksum, '1', $torrentId
|
|
||||||
);
|
|
||||||
|
|
||||||
$groupId = $this->torrent->groupId();
|
|
||||||
self::$cache->delete_multi([
|
|
||||||
"torrent_group_{$groupId}",
|
|
||||||
"torrents_details_{$groupId}",
|
|
||||||
sprintf(\Gazelle\TGroup::CACHE_KEY, $groupId),
|
|
||||||
sprintf(\Gazelle\TGroup::CACHE_TLIST_KEY, $groupId),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'torrentId' => $torrentId,
|
'torrentId' => $this->torrent->id(),
|
||||||
'score' => $score,
|
'score' => $this->torrent->logScore(),
|
||||||
'checksum' => $checksum,
|
'checksum' => $this->torrent->logChecksum(),
|
||||||
'logcheckerVersion' => Logchecker::getLogcheckerVersion(),
|
'logcheckerVersion' => $checkerVersion,
|
||||||
'logSummaries' => $logSummaries
|
'logSummaries' => $logSummaries,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ class Logfile {
|
|||||||
$checker = new Logchecker();
|
$checker = new Logchecker();
|
||||||
$checker->newFile($this->filepath);
|
$checker->newFile($this->filepath);
|
||||||
$checker->parse();
|
$checker->parse();
|
||||||
$this->score = max(0, $checker->getScore());
|
$this->score = max(0, $checker->getScore());
|
||||||
$this->details = $checker->getDetails();
|
$this->details = $checker->getDetails();
|
||||||
$this->checksumState = $checker->getChecksumState();
|
$this->checksumState = $checker->getChecksumState();
|
||||||
$this->text = $checker->getLog();
|
$this->text = $checker->getLog();
|
||||||
$this->ripper = $checker->getRipper() ?? '';
|
$this->ripper = $checker->getRipper() ?? '';
|
||||||
$this->ripperVersion = $checker->getRipperVersion() ?? '';
|
$this->ripperVersion = $checker->getRipperVersion() ?? '';
|
||||||
$this->language = $checker->getLanguage();
|
$this->language = $checker->getLanguage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checksum() { return $this->checksumState === Checksum::CHECKSUM_OK; }
|
public function checksum() { return $this->checksumState === Checksum::CHECKSUM_OK; }
|
||||||
|
|||||||
@@ -3,42 +3,39 @@
|
|||||||
namespace Gazelle;
|
namespace Gazelle;
|
||||||
|
|
||||||
class LogfileSummary {
|
class LogfileSummary {
|
||||||
/** @var Logfile[] */
|
protected array $list;
|
||||||
protected $list;
|
protected bool $allChecksum = true;
|
||||||
protected $allChecksum;
|
protected int $lowestScore = 100;
|
||||||
protected $lowestScore;
|
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct(array $fileList = []) {
|
||||||
$this->list = [];
|
$this->list = [];
|
||||||
|
for ($n = 0, $end = count($fileList['error']); $n < $end; ++$n) {
|
||||||
|
if ($fileList['error'][$n] == UPLOAD_ERR_OK) {
|
||||||
|
$log = new Logfile($fileList['tmp_name'][$n], $fileList['name'][$n]);
|
||||||
|
$this->allChecksum = $this->allChecksum && $log->checksum();
|
||||||
|
$this->lowestScore = min($this->lowestScore, $log->score());
|
||||||
|
$this->list[] = $log;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add(Logfile $log) {
|
public function checksum(): bool {
|
||||||
$this->list[] = $log;
|
|
||||||
$this->allChecksum = is_null($this->allChecksum)
|
|
||||||
? $log->checksum()
|
|
||||||
: $this->allChecksum && $log->checksum();
|
|
||||||
$this->lowestScore = is_null($this->lowestScore)
|
|
||||||
? $log->score()
|
|
||||||
: min($this->lowestScore, $log->score());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checksum() {
|
|
||||||
return $this->allChecksum;
|
return $this->allChecksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checksumStatus() {
|
public function checksumStatus(): string {
|
||||||
return $this->allChecksum ? '1' : '0';
|
return $this->allChecksum ? '1' : '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function overallScore() {
|
public function overallScore(): int {
|
||||||
return is_null($this->lowestScore) ? 0 : $this->lowestScore;
|
return is_null($this->lowestScore) ? 0 : $this->lowestScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function all() {
|
public function all(): array {
|
||||||
return $this->list;
|
return $this->list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function count() {
|
public function total(): int {
|
||||||
return count($this->list);
|
return count($this->list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,27 +99,27 @@ class Torrent extends \Gazelle\BaseManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function create(
|
public function create(
|
||||||
int $tgroupId,
|
int $tgroupId,
|
||||||
int $userId,
|
int $userId,
|
||||||
string $description,
|
string $description,
|
||||||
string $media,
|
string $media,
|
||||||
?string $format,
|
?string $format,
|
||||||
?string $encoding,
|
?string $encoding,
|
||||||
string $infohash,
|
string $infohash,
|
||||||
string $filePath,
|
string $filePath,
|
||||||
array $fileList,
|
array $fileList,
|
||||||
int $size,
|
int $size,
|
||||||
bool $isScene,
|
bool $isScene,
|
||||||
bool $isRemaster,
|
bool $isRemaster,
|
||||||
?int $remasterYear,
|
?int $remasterYear,
|
||||||
string $remasterTitle,
|
string $remasterTitle,
|
||||||
string $remasterRecordLabel,
|
string $remasterRecordLabel,
|
||||||
string $remasterCatalogueNumber,
|
string $remasterCatalogueNumber,
|
||||||
int $logScore = 0,
|
int $logScore = 0,
|
||||||
bool $hasChecksum = false,
|
bool $hasChecksum = false,
|
||||||
bool $hasCue = false,
|
bool $hasCue = false,
|
||||||
bool $hasLog = false,
|
bool $hasLog = false,
|
||||||
bool $hasLogInDB = false,
|
bool $hasLogInDB = false,
|
||||||
): \Gazelle\Torrent {
|
): \Gazelle\Torrent {
|
||||||
self::$db->prepared_query("
|
self::$db->prepared_query("
|
||||||
INSERT INTO torrents (
|
INSERT INTO torrents (
|
||||||
|
|||||||
@@ -3,9 +3,28 @@
|
|||||||
namespace Gazelle\Manager;
|
namespace Gazelle\Manager;
|
||||||
|
|
||||||
class TorrentLog extends \Gazelle\Base {
|
class TorrentLog extends \Gazelle\Base {
|
||||||
|
public function __construct(
|
||||||
|
protected \Gazelle\File\RipLog $ripFiler,
|
||||||
|
protected \Gazelle\File\RipLogHTML $htmlFiler,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function create(\Gazelle\Torrent $torrent, \Gazelle\Logfile $logfile, string $checkerVersion): \Gazelle\TorrentLog {
|
||||||
|
self::$db->prepared_query('
|
||||||
|
INSERT INTO torrents_logs
|
||||||
|
(TorrentID, Score, `Checksum`, FileName, Ripper, RipperVersion, `Language`, ChecksumState, Details, LogcheckerVersion)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
', $torrent->id(), $logfile->score(), $logfile->checksumStatus(), $logfile->filename(),
|
||||||
|
$logfile->ripper(), $logfile->ripperVersion(), $logfile->language(), $logfile->checksumState(), $logfile->detailsAsString(),
|
||||||
|
$checkerVersion
|
||||||
|
);
|
||||||
|
$logId = self::$db->inserted_id();
|
||||||
|
$this->ripFiler->put($logfile->filepath(), [$torrent->id(), $logId]);
|
||||||
|
$this->htmlFiler->put($logfile->text(), [$torrent->id(), $logId]);
|
||||||
|
return $this->findById($torrent, $logId);
|
||||||
|
}
|
||||||
|
|
||||||
public function findById(\Gazelle\Torrent $torrent, int $logId): ?\Gazelle\TorrentLog {
|
public function findById(\Gazelle\Torrent $torrent, int $logId): ?\Gazelle\TorrentLog {
|
||||||
$id = self::$db->scalar("
|
$id = (int)self::$db->scalar("
|
||||||
SELECT LogID FROM torrents_logs WHERE TorrentID = ? AND LogID = ?
|
SELECT LogID FROM torrents_logs WHERE TorrentID = ? AND LogID = ?
|
||||||
", $torrent->id(), $logId
|
", $torrent->id(), $logId
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -220,9 +220,9 @@ class Torrent extends TorrentAbstract {
|
|||||||
if (!$count) {
|
if (!$count) {
|
||||||
self::$db->prepared_query("
|
self::$db->prepared_query("
|
||||||
UPDATE torrents SET
|
UPDATE torrents SET
|
||||||
HasLogDB = '0',
|
HasLogDB = '0',
|
||||||
LogChecksum = '1',
|
LogChecksum = '0',
|
||||||
LogScore = 0
|
LogScore = 0
|
||||||
WHERE ID = ?
|
WHERE ID = ?
|
||||||
", $this->id
|
", $this->id
|
||||||
);
|
);
|
||||||
@@ -231,21 +231,23 @@ class Torrent extends TorrentAbstract {
|
|||||||
UPDATE torrents AS t
|
UPDATE torrents AS t
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT TorrentID,
|
SELECT TorrentID,
|
||||||
min(CASE WHEN Adjusted = '1' OR AdjustedScore != Score THEN AdjustedScore ELSE Score END) AS Score,
|
min(CASE WHEN Adjusted = '1' AND AdjustedScore != Score THEN AdjustedScore ELSE Score END) AS Score,
|
||||||
min(CASE WHEN Adjusted = '1' OR AdjustedChecksum != Checksum THEN AdjustedChecksum ELSE Checksum END) AS Checksum
|
min(CASE WHEN Adjusted = '1' AND AdjustedChecksum != Checksum THEN AdjustedChecksum ELSE Checksum END) AS Checksum
|
||||||
FROM torrents_logs
|
FROM torrents_logs
|
||||||
WHERE TorrentID = ?
|
WHERE TorrentID = ?
|
||||||
GROUP BY TorrentID
|
GROUP BY TorrentID
|
||||||
) AS tl ON (t.ID = tl.TorrentID)
|
) AS tl ON (t.ID = tl.TorrentID)
|
||||||
SET
|
SET
|
||||||
|
t.HasLogDB = '1',
|
||||||
t.LogScore = tl.Score,
|
t.LogScore = tl.Score,
|
||||||
t.LogChecksum = tl.Checksum
|
t.LogChecksum = tl.Checksum
|
||||||
WHERE t.ID = ?
|
WHERE t.ID = ?
|
||||||
", $this->id, $this->id
|
", $this->id, $this->id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$affected = self::$db->affected_rows();
|
||||||
$this->flush();
|
$this->flush();
|
||||||
return self::$db->affected_rows();
|
return $affected;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rescoreLog(int $logId, \Gazelle\Logfile $logfile, string $version): int {
|
public function rescoreLog(int $logId, \Gazelle\Logfile $logfile, string $version): int {
|
||||||
@@ -265,21 +267,6 @@ class Torrent extends TorrentAbstract {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateLogScore(LogfileSummary $summary): int {
|
|
||||||
self::$db->prepared_query("
|
|
||||||
UPDATE torrents SET
|
|
||||||
HasLogDB = '1',
|
|
||||||
LogScore = ?,
|
|
||||||
LogChecksum = ?
|
|
||||||
WHERE ID = ?
|
|
||||||
", $summary->overallScore(), $summary->checksumStatus(),
|
|
||||||
$this->id
|
|
||||||
);
|
|
||||||
$this->flush();
|
|
||||||
self::$cache->delete_value(sprintf(TGroup::CACHE_TLIST_KEY, $this->groupId()));
|
|
||||||
return self::$db->affected_rows();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all logfiles attached to this upload
|
* Remove all logfiles attached to this upload
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ abstract class TorrentAbstract extends BaseObject {
|
|||||||
protected User $viewer;
|
protected User $viewer;
|
||||||
|
|
||||||
public function flush(): TorrentAbstract {
|
public function flush(): TorrentAbstract {
|
||||||
self::$cache->delete_value(sprintf(self::CACHE_KEY, $this->id));
|
self::$cache->delete_multi([
|
||||||
|
sprintf(self::CACHE_KEY, $this->id),
|
||||||
|
"torrent_download_{$this->id}",
|
||||||
|
]);
|
||||||
$this->group()->flush();
|
$this->group()->flush();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ module.exports = defineConfig({
|
|||||||
supportFile: 'tests/cypress/support/e2e.{js,jsx,ts,tsx}',
|
supportFile: 'tests/cypress/support/e2e.{js,jsx,ts,tsx}',
|
||||||
specPattern: 'tests/cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
|
specPattern: 'tests/cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
|
||||||
video: false,
|
video: false,
|
||||||
screenshotOnRunFailure: false
|
screenshotOnRunFailure: false,
|
||||||
|
setupNodeEvents(on, config) {
|
||||||
|
require('cypress-terminal-report/src/installLogsPrinter')(on);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"browser-sync": "^2.27.5",
|
"browser-sync": "^2.27.5",
|
||||||
"browser-sync-webpack-plugin": "^2.2.2",
|
"browser-sync-webpack-plugin": "^2.2.2",
|
||||||
"cypress": "^12.0.2",
|
"cypress": "^12.0.2",
|
||||||
|
"cypress-terminal-report": "^5.0.2",
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.1",
|
||||||
"lint-staged": "^10.5.0",
|
"lint-staged": "^10.5.0",
|
||||||
"stylelint": "^13.3.2",
|
"stylelint": "^13.3.2",
|
||||||
|
|||||||
@@ -4,10 +4,18 @@ $torrent = (new Gazelle\Manager\Torrent)->findById((int)($_GET['id'] ?? 0));
|
|||||||
if (is_null($torrent)) {
|
if (is_null($torrent)) {
|
||||||
json_error('bad parameters');
|
json_error('bad parameters');
|
||||||
}
|
}
|
||||||
|
if ($torrent->uploaderId() != $Viewer->id() && !$Viewer->permitted('admin_add_log')) {
|
||||||
|
json_error('Not your upload.');
|
||||||
|
}
|
||||||
if (empty($_FILES) || empty($_FILES['logfiles'])) {
|
if (empty($_FILES) || empty($_FILES['logfiles'])) {
|
||||||
json_error('no log files uploaded');
|
json_error('no log files uploaded');
|
||||||
}
|
}
|
||||||
|
|
||||||
(new Gazelle\Json\AddLog($torrent, $Viewer, $_FILES['logfiles']))
|
(new Gazelle\Json\AddLog(
|
||||||
|
$torrent,
|
||||||
|
$Viewer,
|
||||||
|
new Gazelle\Manager\TorrentLog(new Gazelle\File\RipLog, new Gazelle\File\RipLogHTML),
|
||||||
|
new Gazelle\LogfileSummary($_FILES['logfiles']),
|
||||||
|
))
|
||||||
->setVersion(1)
|
->setVersion(1)
|
||||||
->emit();
|
->emit();
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
if (isset($_FILES['log']) && is_uploaded_file($_FILES['log']['tmp_name'])) {
|
if (isset($_FILES['log']) && is_uploaded_file($_FILES['log']['tmp_name'])) {
|
||||||
$file = $_FILES['log'];
|
$file = $_FILES['log'];
|
||||||
$isPaste = false;
|
$isPaste = false;
|
||||||
} elseif (!empty($_POST["pastelog"])) {
|
} elseif (!empty($_POST["pastelog"])) {
|
||||||
$fileTmp = tempnam('/tmp', 'log_');
|
$fileTmp = tempnam('/tmp', 'log_');
|
||||||
file_put_contents($fileTmp, $_POST["pastelog"]);
|
file_put_contents($fileTmp, $_POST["pastelog"]);
|
||||||
$file = ['tmp_name' => $fileTmp, 'name' => $fileTmp];
|
$file = [
|
||||||
|
'tmp_name' => $fileTmp,
|
||||||
|
'name' => $fileTmp
|
||||||
|
];
|
||||||
$isPaste = true;
|
$isPaste = true;
|
||||||
} else {
|
} else {
|
||||||
json_error('no log file provided');
|
json_error('no log file provided');
|
||||||
@@ -17,13 +20,11 @@ if (isset($fileTmp)) {
|
|||||||
unlink($fileTmp);
|
unlink($fileTmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = [
|
json_print('success', [
|
||||||
'ripper' => $logfile->ripper(),
|
'ripper' => $logfile->ripper(),
|
||||||
'ripperVersion' => $logfile->ripperVersion(),
|
'ripperVersion' => $logfile->ripperVersion(),
|
||||||
'language' => $logfile->language(),
|
'language' => $logfile->language(),
|
||||||
'score' => $logfile->score(),
|
'score' => $logfile->score(),
|
||||||
'checksum' => $logfile->checksumState(),
|
'checksum' => $logfile->checksumState(),
|
||||||
'issues' => $logfile->details(),
|
'issues' => $logfile->details(),
|
||||||
];
|
]);
|
||||||
|
|
||||||
json_print('success', $response);
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
if (isset($_FILES['log']) && is_uploaded_file($_FILES['log']['tmp_name'])) {
|
if (isset($_FILES['log']) && is_uploaded_file($_FILES['log']['tmp_name'])) {
|
||||||
$file = $_FILES['log'];
|
$file = $_FILES['log'];
|
||||||
$isPaste = false;
|
$isPaste = false;
|
||||||
} elseif (!empty($_POST["pastelog"])) {
|
} elseif (!empty($_POST["pastelog"])) {
|
||||||
$fileTmp = tempnam('/tmp', 'log_');
|
$fileTmp = tempnam('/tmp', 'log_');
|
||||||
file_put_contents($fileTmp, $_POST["pastelog"]);
|
file_put_contents($fileTmp, $_POST["pastelog"]);
|
||||||
$file = ['tmp_name' => $fileTmp, 'name' => $fileTmp];
|
$file = [
|
||||||
|
'tmp_name' => $fileTmp,
|
||||||
|
'name' => $fileTmp
|
||||||
|
];
|
||||||
$isPaste = true;
|
$isPaste = true;
|
||||||
} else {
|
} else {
|
||||||
error('No log file uploaded or file is empty.');
|
error('No log file uploaded or file is empty.');
|
||||||
|
|||||||
@@ -15,37 +15,26 @@ if ($torrent->uploaderId() != $Viewer->id() && !$Viewer->permitted('admin_add_lo
|
|||||||
error('Not your upload.');
|
error('Not your upload.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some browsers will report an empty file when you submit, prune those out
|
|
||||||
$_FILES['logfiles']['name'] = array_filter($_FILES['logfiles']['name'], fn($Name) => !empty($Name));
|
|
||||||
if (count($_FILES['logfiles']['name']) == 0) {
|
|
||||||
error("No logfiles uploaded.\n");
|
|
||||||
}
|
|
||||||
$action = in_array($_POST['from_action'], ['upload', 'update']) ? $_POST['from_action'] : 'upload';
|
$action = in_array($_POST['from_action'], ['upload', 'update']) ? $_POST['from_action'] : 'upload';
|
||||||
|
$logfileSummary = new Gazelle\LogfileSummary($_FILES['logfiles']);
|
||||||
|
|
||||||
$ripFiler = new Gazelle\File\RipLog;
|
if (!$logfileSummary->total()) {
|
||||||
$ripFiler->remove([$torrent->id(), null]);
|
error("No logfiles uploaded.");
|
||||||
|
} else {
|
||||||
|
$ripFiler = new Gazelle\File\RipLog;
|
||||||
|
$htmlFiler = new Gazelle\File\RipLogHTML;
|
||||||
|
|
||||||
$htmlFiler = new Gazelle\File\RipLogHTML;
|
$torrent->removeLogDb();
|
||||||
$htmlFiler->remove([$torrent->id(), null]);
|
$ripFiler->remove([$torrent->id(), null]);
|
||||||
|
$htmlFiler->remove([$torrent->id(), null]);
|
||||||
|
$torrentLogManager = new Gazelle\Manager\TorrentLog($ripFiler, $htmlFiler);
|
||||||
|
|
||||||
$torrent->removeLogDb();
|
$checkerVersion = Logchecker::getLogcheckerVersion();
|
||||||
|
foreach($logfileSummary->all() as $logfile) {
|
||||||
$logfileSummary = new Gazelle\LogfileSummary;
|
$torrentLogManager->create($torrent, $logfile, $checkerVersion);
|
||||||
foreach ($_FILES['logfiles']['name'] as $Pos => $File) {
|
|
||||||
if (!$_FILES['logfiles']['size'][$Pos]) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
$logfile = new Gazelle\Logfile(
|
$torrent->modifyLogscore();
|
||||||
$_FILES['logfiles']['tmp_name'][$Pos],
|
|
||||||
$_FILES['logfiles']['name'][$Pos]
|
|
||||||
);
|
|
||||||
$logfileSummary->add($logfile);
|
|
||||||
$logId = $torrent->addLogDb($logfile, Logchecker::getLogcheckerVersion());
|
|
||||||
|
|
||||||
$ripFiler->put($logfile->filepath(), [$torrent->id(), $logId]);
|
|
||||||
$htmlFiler->put($logfile->text(), [$torrent->id(), $logId]);
|
|
||||||
}
|
}
|
||||||
$torrent->updateLogScore($logfileSummary);
|
|
||||||
|
|
||||||
echo $Twig->render('logchecker/result.twig', [
|
echo $Twig->render('logchecker/result.twig', [
|
||||||
'summary' => $logfileSummary->all(),
|
'summary' => $logfileSummary->all(),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
authorize();
|
||||||
if (!$Viewer->permitted('users_mod')) {
|
if (!$Viewer->permitted('users_mod')) {
|
||||||
error(403);
|
error(403);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ $torrent = (new Gazelle\Manager\Torrent)->findById((int)($_GET['torrentid'] ?? 0
|
|||||||
if (is_null($torrent)) {
|
if (is_null($torrent)) {
|
||||||
error(404);
|
error(404);
|
||||||
}
|
}
|
||||||
$tlog = (new Gazelle\Manager\TorrentLog)->findById($torrent, (int)($_GET['logid'] ?? 0));
|
$tlog = (new Gazelle\Manager\TorrentLog(new Gazelle\File\RipLog, new Gazelle\File\RipLogHTML))->findById($torrent, (int)($_GET['logid'] ?? 0));
|
||||||
if (is_null($tlog)) {
|
if (is_null($tlog)) {
|
||||||
error(404);
|
error(404);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
authorize();
|
||||||
if (!$Viewer->permitted('torrents_delete')) {
|
if (!$Viewer->permitted('torrents_delete')) {
|
||||||
error(403);
|
error(403);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,16 +47,16 @@ if (isset($_POST['album_desc'])) {
|
|||||||
$Properties['GroupDescription'] = trim($_POST['album_desc']);
|
$Properties['GroupDescription'] = trim($_POST['album_desc']);
|
||||||
}
|
}
|
||||||
if ($Properties['Remastered']) {
|
if ($Properties['Remastered']) {
|
||||||
$Properties['UnknownRelease'] = isset($_POST['unknown']);
|
$Properties['UnknownRelease'] = isset($_POST['unknown']);
|
||||||
$Properties['RemasterYear'] = isset($_POST['remaster_year']) ? (int)$_POST['remaster_year'] : null;
|
$Properties['RemasterYear'] = isset($_POST['remaster_year']) ? (int)$_POST['remaster_year'] : null;
|
||||||
$Properties['RemasterTitle'] = trim($_POST['remaster_title'] ?? '');
|
$Properties['RemasterTitle'] = trim($_POST['remaster_title'] ?? '');
|
||||||
$Properties['RemasterRecordLabel'] = trim($_POST['remaster_record_label'] ?? '');
|
$Properties['RemasterRecordLabel'] = trim($_POST['remaster_record_label'] ?? '');
|
||||||
$Properties['RemasterCatalogueNumber'] = trim($_POST['remaster_catalogue_number'] ?? '');
|
$Properties['RemasterCatalogueNumber'] = trim($_POST['remaster_catalogue_number'] ?? '');
|
||||||
} else {
|
} else {
|
||||||
$Properties['UnknownRelease'] = false;
|
$Properties['UnknownRelease'] = false;
|
||||||
$Properties['RemasterYear'] = null;
|
$Properties['RemasterYear'] = null;
|
||||||
$Properties['RemasterTitle'] = '';
|
$Properties['RemasterTitle'] = '';
|
||||||
$Properties['RemasterRecordLabel'] = '';
|
$Properties['RemasterRecordLabel'] = '';
|
||||||
$Properties['RemasterCatalogueNumber'] = '';
|
$Properties['RemasterCatalogueNumber'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,42 +199,20 @@ foreach ($current as $key => $value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$logfileSummary = new Gazelle\LogfileSummary($_FILES['logfiles']);
|
||||||
|
|
||||||
|
//******************************************************************************//
|
||||||
|
//--------------- Start database stuff -----------------------------------------//
|
||||||
|
|
||||||
$db->begin_transaction(); // It's all or nothing
|
$db->begin_transaction(); // It's all or nothing
|
||||||
|
|
||||||
// Some browsers will report an empty file when you submit, prune those out
|
if ($logfileSummary->total()) {
|
||||||
if (isset($_FILES['logfiles'])) {
|
$torrentLogManager = new Gazelle\Manager\TorrentLog(new Gazelle\File\RipLog, new Gazelle\File\RipLogHTML);
|
||||||
$_FILES['logfiles']['name'] = array_filter($_FILES['logfiles']['name'], fn($name) => !empty($name));
|
$checkerVersion = Logchecker::getLogcheckerVersion();
|
||||||
|
foreach($logfileSummary->all() as $logfile) {
|
||||||
$logfileSummary = new Gazelle\LogfileSummary;
|
$torrentLogManager->create($torrent, $logfile, $checkerVersion);
|
||||||
$logfiles = [];
|
|
||||||
if (count($_FILES['logfiles']['name']) > 0) {
|
|
||||||
ini_set('upload_max_filesize', 1_000_000);
|
|
||||||
$ripFiler = new Gazelle\File\RipLog;
|
|
||||||
$htmlFiler = new Gazelle\File\RipLogHTML;
|
|
||||||
foreach ($_FILES['logfiles']['name'] as $Pos => $File) {
|
|
||||||
if (!$_FILES['logfiles']['size'][$Pos]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$logfile = new Gazelle\Logfile(
|
|
||||||
$_FILES['logfiles']['tmp_name'][$Pos],
|
|
||||||
$_FILES['logfiles']['name'][$Pos]
|
|
||||||
);
|
|
||||||
$logfileSummary->add($logfile);
|
|
||||||
|
|
||||||
$db->prepared_query('
|
|
||||||
INSERT INTO torrents_logs
|
|
||||||
(TorrentID, Score, `Checksum`, FileName, Ripper, RipperVersion, `Language`, ChecksumState, LogcheckerVersion, Details)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
', $TorrentID, $logfile->score(), $logfile->checksumStatus(), $logfile->filename(), $logfile->ripper(),
|
|
||||||
$logfile->ripperVersion(), $logfile->language(), $logfile->checksumState(),
|
|
||||||
Logchecker::getLogcheckerVersion(), $logfile->detailsAsString()
|
|
||||||
);
|
|
||||||
$LogID = $db->inserted_id();
|
|
||||||
$ripFiler->put($logfile->filepath(), [$TorrentID, $LogID]);
|
|
||||||
$htmlFiler->put($logfile->text(), [$TorrentID, $LogID]);
|
|
||||||
}
|
|
||||||
$torrent->updateLogScore($logfileSummary);
|
|
||||||
}
|
}
|
||||||
|
$torrent->modifyLogscore();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update info for the torrent
|
// Update info for the torrent
|
||||||
@@ -303,5 +281,4 @@ $changeLog = implode(', ', $change);
|
|||||||
. $Viewer->username() . " ($changeLog)");
|
. $Viewer->username() . " ($changeLog)");
|
||||||
|
|
||||||
$torrent->flush();
|
$torrent->flush();
|
||||||
$Cache->delete_value("torrent_download_$TorrentID");
|
|
||||||
header("Location: " . $torrent->location());
|
header("Location: " . $torrent->location());
|
||||||
|
|||||||
@@ -24,18 +24,18 @@ $Properties['Title'] = isset($_POST['title']) ? trim($_POST['title']) : null;
|
|||||||
// Remastered is an Enum in the DB
|
// Remastered is an Enum in the DB
|
||||||
$Properties['Remastered'] = !empty($_POST['remaster']) ? '1' : '0';
|
$Properties['Remastered'] = !empty($_POST['remaster']) ? '1' : '0';
|
||||||
if ($Properties['Remastered'] || !empty($_POST['unknown'])) {
|
if ($Properties['Remastered'] || !empty($_POST['unknown'])) {
|
||||||
$Properties['UnknownRelease'] = !empty($_POST['unknown']) ? 1 : 0;
|
$Properties['UnknownRelease'] = !empty($_POST['unknown']) ? 1 : 0;
|
||||||
$Properties['RemasterYear'] = isset($_POST['remaster_year']) ? (int)$_POST['remaster_year'] : null;
|
$Properties['RemasterYear'] = isset($_POST['remaster_year']) ? (int)$_POST['remaster_year'] : null;
|
||||||
$_POST['remaster_year'] = $Properties['RemasterYear'];
|
$_POST['remaster_year'] = $Properties['RemasterYear'];
|
||||||
$Properties['RemasterTitle'] = trim($_POST['remaster_title'] ?? '');
|
$Properties['RemasterTitle'] = trim($_POST['remaster_title'] ?? '');
|
||||||
$Properties['RemasterRecordLabel'] = trim($_POST['remaster_record_label'] ?? '');
|
$Properties['RemasterRecordLabel'] = trim($_POST['remaster_record_label'] ?? '');
|
||||||
$Properties['RemasterCatalogueNumber'] = trim($_POST['remaster_catalogue_number'] ?? '');
|
$Properties['RemasterCatalogueNumber'] = trim($_POST['remaster_catalogue_number'] ?? '');
|
||||||
}
|
}
|
||||||
if (!$Properties['Remastered'] || $Properties['UnknownRelease']) {
|
if (!$Properties['Remastered'] || $Properties['UnknownRelease']) {
|
||||||
$Properties['UnknownRelease'] = 1;
|
$Properties['UnknownRelease'] = 1;
|
||||||
$Properties['RemasterYear'] = null;
|
$Properties['RemasterYear'] = null;
|
||||||
$Properties['RemasterTitle'] = '';
|
$Properties['RemasterTitle'] = '';
|
||||||
$Properties['RemasterRecordLabel'] = '';
|
$Properties['RemasterRecordLabel'] = '';
|
||||||
$Properties['RemasterCatalogueNumber'] = '';
|
$Properties['RemasterCatalogueNumber'] = '';
|
||||||
}
|
}
|
||||||
$Properties['Year'] = isset($_POST['year']) ? (int)$_POST['year'] : null;
|
$Properties['Year'] = isset($_POST['year']) ? (int)$_POST['year'] : null;
|
||||||
@@ -472,24 +472,6 @@ if ($Err) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************************************//
|
|
||||||
//--------------- Start database stuff -----------------------------------------//
|
|
||||||
|
|
||||||
$logfileSummary = new Gazelle\LogfileSummary;
|
|
||||||
if ($HasLog == '1' && isset($_FILES['logfiles'])) {
|
|
||||||
foreach (array_keys($_FILES['logfiles']['error']) as $n) {
|
|
||||||
if ($_FILES['logfiles']['error'][$n] == UPLOAD_ERR_OK) {
|
|
||||||
$logfileSummary->add(
|
|
||||||
new Gazelle\Logfile(
|
|
||||||
$_FILES['logfiles']['tmp_name'][$n],
|
|
||||||
$_FILES['logfiles']['name'][$n]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$LogInDB = count($logfileSummary->all()) ? '1' : '0';
|
|
||||||
|
|
||||||
$tgroup = null;
|
$tgroup = null;
|
||||||
$NoRevision = false;
|
$NoRevision = false;
|
||||||
if ($isMusicUpload) {
|
if ($isMusicUpload) {
|
||||||
@@ -527,7 +509,11 @@ $IsNewGroup = is_null($tgroup);
|
|||||||
//Needs to be here as it isn't set for add format until now
|
//Needs to be here as it isn't set for add format until now
|
||||||
$LogName .= $Properties['Title'];
|
$LogName .= $Properties['Title'];
|
||||||
|
|
||||||
//----- Start inserts
|
$logfileSummary = new Gazelle\LogfileSummary($_FILES['logfiles']);
|
||||||
|
$LogInDB = $logfileSummary->total() ? '1' : '0';
|
||||||
|
|
||||||
|
//******************************************************************************//
|
||||||
|
//--------------- Start database stuff -----------------------------------------//
|
||||||
|
|
||||||
$Debug->set_flag('upload: database begin transaction');
|
$Debug->set_flag('upload: database begin transaction');
|
||||||
$db = Gazelle\DB::DB();
|
$db = Gazelle\DB::DB();
|
||||||
@@ -613,58 +599,45 @@ $extraFile = [];
|
|||||||
$trackerUpdate = [];
|
$trackerUpdate = [];
|
||||||
|
|
||||||
foreach ($ExtraTorrentsInsert as $ExtraTorrent) {
|
foreach ($ExtraTorrentsInsert as $ExtraTorrent) {
|
||||||
$db->prepared_query("
|
$torrentExtra = $torMan->create(
|
||||||
INSERT INTO torrents
|
tgroupId: $GroupID,
|
||||||
(GroupID, UserID, Media, Format, Encoding,
|
userId: $Viewer->id(),
|
||||||
Remastered, RemasterYear, RemasterTitle, RemasterRecordLabel, RemasterCatalogueNumber,
|
description: $ExtraTorrent['TorrentDescription'],
|
||||||
info_hash, FileCount, FileList, FilePath, Size, Description,
|
media: $Properties['Media'],
|
||||||
Time, LogScore, HasLog, HasCue, FreeTorrent, FreeLeechType)
|
format: $ExtraTorrent['Format'],
|
||||||
VALUES
|
encoding: $ExtraTorrent['Encoding'],
|
||||||
(?, ?, ?, ?, ?,
|
infohash: $ExtraTorrent['InfoHash'],
|
||||||
?, ?, ?, ?, ?,
|
filePath: $ExtraTorrent['FilePath'],
|
||||||
?, ?, ?, ?, ?, ?,
|
fileList: $ExtraTorrent['FileString'],
|
||||||
now(), 0, '0', '0', '0', '0')
|
size: $ExtraTorrent['TotalSize'],
|
||||||
", $GroupID, $Viewer->id(), $Properties['Media'], $ExtraTorrent['Format'], $ExtraTorrent['Encoding'],
|
isScene: $Properties['Scene'],
|
||||||
$Properties['Remastered'], $Properties['RemasterYear'], $Properties['RemasterTitle'], $Properties['RemasterRecordLabel'], $Properties['RemasterCatalogueNumber'],
|
isRemaster: $Properties['Remastered'],
|
||||||
$ExtraTorrent['InfoHash'], $ExtraTorrent['NumFiles'], $ExtraTorrent['FileString'],
|
remasterYear: $Properties['RemasterYear'],
|
||||||
$ExtraTorrent['FilePath'], $ExtraTorrent['TotalSize'], $ExtraTorrent['TorrentDescription']
|
remasterTitle: $Properties['RemasterTitle'],
|
||||||
|
remasterRecordLabel: $Properties['RemasterRecordLabel'],
|
||||||
|
remasterCatalogueNumber: $Properties['RemasterCatalogueNumber'],
|
||||||
);
|
);
|
||||||
$ExtraTorrentID = $db->inserted_id();
|
|
||||||
$db->prepared_query('
|
|
||||||
INSERT INTO torrents_leech_stats (TorrentID)
|
|
||||||
VALUES (?)
|
|
||||||
', $ExtraTorrentID
|
|
||||||
);
|
|
||||||
$torrentExtra = new Gazelle\Torrent($ExtraTorrentID);
|
|
||||||
|
|
||||||
$torMan->flushFoldernameCache($ExtraTorrent['FilePath']);
|
$torMan->flushFoldernameCache($torrentExtra->path());
|
||||||
$folderCheck[] = $ExtraTorrent['FilePath'];
|
$folderCheck[] = $torrentExtra->path();
|
||||||
$trackerUpdate[$ExtraTorrentID] = rawurlencode($ExtraTorrent['InfoHash']);
|
$trackerUpdate[$torrentExtra->id()] = rawurlencode($torrentExtra->infohash());
|
||||||
$bonusTotal += $bonus->torrentValue($torrentExtra);
|
$bonusTotal += $bonus->torrentValue($torrentExtra);
|
||||||
|
|
||||||
$extraFile[$ExtraTorrentID] = [
|
$extraFile[$torrentExtra->id()] = [
|
||||||
'payload' => $ExtraTorrent['TorEnc'],
|
'payload' => $ExtraTorrent['TorEnc'],
|
||||||
'size' => number_format($ExtraTorrent['TotalSize'] / (1024 * 1024), 2)
|
'size' => number_format($torrentExtra->size() / (1024 * 1024), 2)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************************************//
|
//******************************************************************************//
|
||||||
//--------------- Write Files To Disk ------------------------------------------//
|
//--------------- Write Files To Disk ------------------------------------------//
|
||||||
|
|
||||||
$ripFiler = new Gazelle\File\RipLog;
|
if ($logfileSummary->total()) {
|
||||||
$htmlFiler = new Gazelle\File\RipLogHTML;
|
$torrentLogManager = new Gazelle\Manager\TorrentLog(new Gazelle\File\RipLog, new Gazelle\File\RipLogHTML);
|
||||||
foreach($logfileSummary->all() as $logfile) {
|
$checkerVersion = Logchecker::getLogcheckerVersion();
|
||||||
$db->prepared_query('
|
foreach($logfileSummary->all() as $logfile) {
|
||||||
INSERT INTO torrents_logs
|
$torrentLogManager->create($torrent, $logfile, $checkerVersion);
|
||||||
(TorrentID, Score, `Checksum`, FileName, Ripper, RipperVersion, `Language`, ChecksumState, LogcheckerVersion, Details)
|
}
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
', $TorrentID, $logfile->score(), $logfile->checksumStatus(), $logfile->filename(),
|
|
||||||
$logfile->ripper(), $logfile->ripperVersion(), $logfile->language(), $logfile->checksumState(),
|
|
||||||
Logchecker::getLogcheckerVersion(), $logfile->detailsAsString()
|
|
||||||
);
|
|
||||||
$LogID = $db->inserted_id();
|
|
||||||
$ripFiler->put($logfile->filepath(), [$TorrentID, $LogID]);
|
|
||||||
$htmlFiler->put($logfile->text(), [$TorrentID, $LogID]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$log = new Gazelle\Log;
|
$log = new Gazelle\Log;
|
||||||
@@ -675,7 +648,7 @@ $log->torrent($GroupID, $TorrentID, $Viewer->id(), 'uploaded ('.number_format($T
|
|||||||
foreach ($extraFile as $id => $info) {
|
foreach ($extraFile as $id => $info) {
|
||||||
$torrentFiler->put($info['payload'], $id);
|
$torrentFiler->put($info['payload'], $id);
|
||||||
$log->torrent($GroupID, $id, $Viewer->id(), "uploaded ({$info['size']} MiB)")
|
$log->torrent($GroupID, $id, $Viewer->id(), "uploaded ({$info['size']} MiB)")
|
||||||
->general("Torrent $ExtraTorrentID ($LogName) ({$info['size']} MiB) was uploaded by " . $Viewer->username());
|
->general("Torrent $id ($LogName) ({$info['size']} MiB) was uploaded by " . $Viewer->username());
|
||||||
}
|
}
|
||||||
|
|
||||||
$db->commit(); // We have a usable upload, any subsequent failures can be repaired ex post facto
|
$db->commit(); // We have a usable upload, any subsequent failures can be repaired ex post facto
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
{% if viewer.permitted('users_mod') %}
|
{% if viewer.permitted('users_mod') %}
|
||||||
<div style="padding: 10px; float: right"><a class="brackets" href="torrents.php?action=editlog&torrentid={{ id }}&logid={{ log.id }}">Edit Log</a>
|
<div style="padding: 10px; float: right"><a class="brackets" href="torrents.php?action=editlog&torrentid={{ id }}&logid={{ log.id }}">Edit Log</a>
|
||||||
<a class="brackets" onclick="return confirm('Are you sure you want to deleted this log? There is NO undo!');"
|
<a class="brackets" onclick="return confirm('Are you sure you want to deleted this log? There is NO undo!');"
|
||||||
href="torrents.php?action=deletelog&torrentid={{ id }}&logid={{ log.id }}">Delete Log</a>
|
href="torrents.php?action=deletelog&torrentid={{ id }}&logid={{ log.id }}&auth={{ viewer.auth }}">Delete Log</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -71,6 +71,6 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
No logs found!
|
No logs found!
|
||||||
{% if viewer.permitted('torrents_delete') %}
|
{% if viewer.permitted('torrents_delete') %}
|
||||||
<a class="brackets" href="torrents.php?action=removelogs&torrentid={{ id }}">Repair DB</a>
|
<a class="brackets" href="torrents.php?action=removelogs&torrentid={{ id }}&auth={{ viewer.auth }}">Repair DB</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ describe('page loads as admin', () => {
|
|||||||
"/top10.php",
|
"/top10.php",
|
||||||
"/torrents.php",
|
"/torrents.php",
|
||||||
"/torrents.php?action=advanced&artistname=doesnotexist",
|
"/torrents.php?action=advanced&artistname=doesnotexist",
|
||||||
"/upload.php",
|
|
||||||
"/user.php",
|
"/user.php",
|
||||||
"/user.php?id=1",
|
"/user.php?id=1",
|
||||||
"/user.php?action=edit&id=1",
|
"/user.php?action=edit&id=1",
|
||||||
@@ -48,7 +47,7 @@ describe('page loads as admin', () => {
|
|||||||
})
|
})
|
||||||
it(`should have a footer: ${url}`, () => {
|
it(`should have a footer: ${url}`, () => {
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.contains(`Site and design © ${date.getFullYear()} Gazelle`);
|
cy.ensureFooter();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
describe('uploading torrent', () => {
|
describe('uploading torrent', () => {
|
||||||
let date = new Date();
|
|
||||||
let footer = `Site and design © ${date.getFullYear()} Gazelle`;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.loginUser();
|
cy.loginUser();
|
||||||
})
|
})
|
||||||
|
|
||||||
it('upload music torrent', () => {
|
it('upload music torrent', () => {
|
||||||
cy.visit('/upload.php');
|
cy.visit('/upload.php');
|
||||||
|
cy.ensureFooter();
|
||||||
cy.get('#file').selectFile('tests/cypress/files/valid_torrent.torrent')
|
cy.get('#file').selectFile('tests/cypress/files/valid_torrent.torrent')
|
||||||
cy.get("#categories").select('Music');
|
cy.get("#categories").select('Music');
|
||||||
cy.get("#releasetype").select('Album');
|
cy.get("#releasetype").select('Album');
|
||||||
@@ -41,11 +39,12 @@ describe('uploading torrent', () => {
|
|||||||
cy.contains('Some Artist');
|
cy.contains('Some Artist');
|
||||||
cy.contains('2022');
|
cy.contains('2022');
|
||||||
cy.contains('Cool Test Label!');
|
cy.contains('Cool Test Label!');
|
||||||
cy.contains(footer);
|
cy.ensureFooter();
|
||||||
})
|
})
|
||||||
|
|
||||||
it('upload torrent to existing group', () => {
|
it('upload torrent to existing group', () => {
|
||||||
cy.visit('/upload.php');
|
cy.visit('/upload.php');
|
||||||
|
cy.ensureFooter();
|
||||||
cy.get('#file').selectFile('tests/cypress/files/valid_torrent_2.torrent')
|
cy.get('#file').selectFile('tests/cypress/files/valid_torrent_2.torrent')
|
||||||
cy.get("#categories").select('Music');
|
cy.get("#categories").select('Music');
|
||||||
cy.get("#releasetype").select('Album');
|
cy.get("#releasetype").select('Album');
|
||||||
@@ -76,6 +75,82 @@ describe('uploading torrent', () => {
|
|||||||
cy.contains('2022');
|
cy.contains('2022');
|
||||||
cy.contains('Cool Test Label!');
|
cy.contains('Cool Test Label!');
|
||||||
cy.contains('[CD / FLAC / Lossless / Log (100%)]');
|
cy.contains('[CD / FLAC / Lossless / Log (100%)]');
|
||||||
cy.contains(footer);
|
cy.ensureFooter();
|
||||||
|
})
|
||||||
|
|
||||||
|
it('re-attach log to upload', () => {
|
||||||
|
// find torrent id
|
||||||
|
cy.visit('/torrents.php?type=uploaded');
|
||||||
|
cy.ensureFooter();
|
||||||
|
|
||||||
|
// bunch of callbacks have been flattened below
|
||||||
|
cy.get('.group_info').contains('Log (100%)').first()
|
||||||
|
.find('a[href*="torrents.php?"][href*="torrentid="]').first()
|
||||||
|
.invoke('attr', 'href').then((torrent_url) => {
|
||||||
|
let torrent_id = torrent_url.match(/[&?]torrentid=([0-9]+)/)[1];
|
||||||
|
cy.visit(torrent_url);
|
||||||
|
cy.ensureFooter();
|
||||||
|
cy.get(`#torrent_${torrent_id}`).contains('View log').click();
|
||||||
|
cy.get(`a[href*="view.php?type=riplog&id=${torrent_id}."]`).first()
|
||||||
|
.invoke('attr', 'href').then((log_url) => {
|
||||||
|
|
||||||
|
let log_id = log_url.match(/&id=[0-9]+\.([0-9]+)/)[1];
|
||||||
|
|
||||||
|
// delete existing log
|
||||||
|
cy.loginAdmin();
|
||||||
|
cy.visit('/');
|
||||||
|
cy.window()
|
||||||
|
.then((window) => {
|
||||||
|
cy.window().should('have.property', 'authkey')
|
||||||
|
cy.visit('/torrents.php', {qs: {
|
||||||
|
action: 'deletelog',
|
||||||
|
torrentid: torrent_id,
|
||||||
|
logid: log_id,
|
||||||
|
auth: window.authkey
|
||||||
|
}})
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.loginUser();
|
||||||
|
// verify log was correctly removed
|
||||||
|
cy.visit(torrent_url);
|
||||||
|
cy.contains('Log (100%)').should('not.exist');
|
||||||
|
cy.ensureFooter();
|
||||||
|
// set up api token
|
||||||
|
cy.visit('/user.php?action=token&do=generate',
|
||||||
|
{method: 'POST', body: {token_name: 'test_reattach_log'}});
|
||||||
|
cy.ensureFooter();
|
||||||
|
|
||||||
|
// upload log
|
||||||
|
cy.get('.box2 > .pad > strong').invoke('text').then((api_key) => {
|
||||||
|
cy.fixture('../files/valid_log_eac.log', 'binary').then( (log_bin) => {
|
||||||
|
// File in binary format gets converted to blob so it can be sent as Form data
|
||||||
|
const blob = Cypress.Blob.binaryStringToBlob(log_bin, 'application/octet-stream');
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('logfiles[]', blob, 'eac.log');
|
||||||
|
cy.request({
|
||||||
|
url: '/ajax.php',
|
||||||
|
qs: {action: 'add_log', id: torrent_id},
|
||||||
|
method: 'POST',
|
||||||
|
headers: {authorization: `token ${api_key}`,
|
||||||
|
'content-type': 'multipart/form-data'},
|
||||||
|
body: formData
|
||||||
|
}).then( (response) => {
|
||||||
|
// it's an ArrayBuffer but for some reason instanceof ArrayBuffer is false
|
||||||
|
// and its stringifyed version is "{}"
|
||||||
|
let body = typeof response.body === 'object' ?
|
||||||
|
new TextDecoder().decode(response.body) : response.body;
|
||||||
|
try {
|
||||||
|
body = JSON.parse(body);
|
||||||
|
} catch (e) {
|
||||||
|
cy.logCli("bad response body: " + body);
|
||||||
|
}
|
||||||
|
expect(body).to.have.property('status', 'success');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
// verify
|
||||||
|
cy.visit(torrent_url);
|
||||||
|
cy.ensureFooter();
|
||||||
|
cy.contains('Log (100%)');
|
||||||
|
})})});
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
// -- This will overwrite an existing command --
|
// -- This will overwrite an existing command --
|
||||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||||
|
|
||||||
|
const date = new Date();
|
||||||
|
const footer = `Site and design © ${date.getFullYear()} Gazelle`;
|
||||||
|
|
||||||
Cypress.Commands.add('login', (username, password) => {
|
Cypress.Commands.add('login', (username, password) => {
|
||||||
// https://www.cypress.io/blog/2021/08/04/authenticate-faster-in-tests-cy-session-command/
|
// https://www.cypress.io/blog/2021/08/04/authenticate-faster-in-tests-cy-session-command/
|
||||||
cy.session([username, password], () => {
|
cy.session([username, password], () => {
|
||||||
@@ -42,3 +45,15 @@ Cypress.Commands.add('loginAdmin', () => {
|
|||||||
Cypress.Commands.add('loginUser', () => {
|
Cypress.Commands.add('loginUser', () => {
|
||||||
cy.login('user', 'password');
|
cy.login('user', 'password');
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Cypress.Commands.add('ensureFooter', () => {
|
||||||
|
cy.contains(footer);
|
||||||
|
})
|
||||||
|
|
||||||
|
Cypress.Commands.add('logCli', (msg) => {
|
||||||
|
// somehow cypress-terminal-report doesn't pick up cy.log()
|
||||||
|
Cypress.log({
|
||||||
|
name: "logCli",
|
||||||
|
message: msg
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|||||||
@@ -13,12 +13,14 @@
|
|||||||
// https://on.cypress.io/configuration
|
// https://on.cypress.io/configuration
|
||||||
// ***********************************************************
|
// ***********************************************************
|
||||||
|
|
||||||
// Import commands.js using ES2015 syntax:
|
require('cypress-terminal-report/src/installLogsCollector')({
|
||||||
|
xhr: {
|
||||||
|
printHeaderData: true,
|
||||||
|
printRequestData: true
|
||||||
|
}
|
||||||
|
});
|
||||||
import './commands'
|
import './commands'
|
||||||
|
|
||||||
// Alternatively you can use CommonJS syntax:
|
|
||||||
// require('./commands')
|
|
||||||
|
|
||||||
Cypress.on('fail', (err, runnable) => {
|
Cypress.on('fail', (err, runnable) => {
|
||||||
/**
|
/**
|
||||||
* add DOM html to error message
|
* add DOM html to error message
|
||||||
|
|||||||
38
yarn.lock
38
yarn.lock
@@ -3098,6 +3098,16 @@ cyclist@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
|
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
|
||||||
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
|
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
|
||||||
|
|
||||||
|
cypress-terminal-report@^5.0.2:
|
||||||
|
version "5.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/cypress-terminal-report/-/cypress-terminal-report-5.0.2.tgz#923db46f06c4b32021c48da0177065ea1af2d999"
|
||||||
|
integrity sha512-YJ6HODTvxKD0FYQX2p3f1DlBRcJcMJjRh3JWZZrBte4dQdnTuIElb4jPh3zbcqsV4MJ+QwF6XyJoXybZgg6kHg==
|
||||||
|
dependencies:
|
||||||
|
chalk "^4.0.0"
|
||||||
|
fs-extra "^10.1.0"
|
||||||
|
semver "^7.3.5"
|
||||||
|
tv4 "^1.3.0"
|
||||||
|
|
||||||
cypress@^12.0.2:
|
cypress@^12.0.2:
|
||||||
version "12.0.2"
|
version "12.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.0.2.tgz#0437abf9d97ad4a972ab554968d58211b0ce4ae5"
|
resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.0.2.tgz#0437abf9d97ad4a972ab554968d58211b0ce4ae5"
|
||||||
@@ -4241,6 +4251,15 @@ fs-extra@3.0.1:
|
|||||||
jsonfile "^3.0.0"
|
jsonfile "^3.0.0"
|
||||||
universalify "^0.1.0"
|
universalify "^0.1.0"
|
||||||
|
|
||||||
|
fs-extra@^10.1.0:
|
||||||
|
version "10.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
|
||||||
|
integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
|
||||||
|
dependencies:
|
||||||
|
graceful-fs "^4.2.0"
|
||||||
|
jsonfile "^6.0.1"
|
||||||
|
universalify "^2.0.0"
|
||||||
|
|
||||||
fs-extra@^7.0.1:
|
fs-extra@^7.0.1:
|
||||||
version "7.0.1"
|
version "7.0.1"
|
||||||
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz"
|
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz"
|
||||||
@@ -5852,6 +5871,13 @@ lru-cache@^5.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
yallist "^3.0.2"
|
yallist "^3.0.2"
|
||||||
|
|
||||||
|
lru-cache@^6.0.0:
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
|
||||||
|
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
|
||||||
|
dependencies:
|
||||||
|
yallist "^4.0.0"
|
||||||
|
|
||||||
make-dir@^1.0.0:
|
make-dir@^1.0.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz"
|
resolved "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz"
|
||||||
@@ -8124,6 +8150,13 @@ semver@^7.3.2:
|
|||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
||||||
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
|
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
|
||||||
|
|
||||||
|
semver@^7.3.5:
|
||||||
|
version "7.3.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
|
||||||
|
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
|
||||||
|
dependencies:
|
||||||
|
lru-cache "^6.0.0"
|
||||||
|
|
||||||
send@0.16.2:
|
send@0.16.2:
|
||||||
version "0.16.2"
|
version "0.16.2"
|
||||||
resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1"
|
resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1"
|
||||||
@@ -9247,6 +9280,11 @@ tunnel-agent@^0.6.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
tv4@^1.3.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tv4/-/tv4-1.3.0.tgz#d020c846fadd50c855abb25ebaecc68fc10f7963"
|
||||||
|
integrity sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==
|
||||||
|
|
||||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||||
version "0.14.5"
|
version "0.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||||
|
|||||||
Reference in New Issue
Block a user