mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
Better better
This commit is contained in:
@@ -10,7 +10,7 @@ class Base {
|
||||
protected $cache;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = new \DB_MYSQL;
|
||||
$this->cache = \G::$Cache;
|
||||
$this->db = \G::$DB;
|
||||
}
|
||||
}
|
||||
|
||||
315
app/Manager/Better.php
Normal file
315
app/Manager/Better.php
Normal file
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
|
||||
namespace Gazelle\Manager;
|
||||
|
||||
class Better extends \Gazelle\Base
|
||||
{
|
||||
protected $releaseTypes;
|
||||
|
||||
public function __construct(array $releaseTypes) {
|
||||
parent::__construct();
|
||||
$this->releaseTypes = $releaseTypes;
|
||||
}
|
||||
|
||||
public function removeAttribute(string $type, int $id) {
|
||||
$table = $this->badMap[$type] ?? null;
|
||||
if (!$table) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->db->prepared_query(sprintf('
|
||||
DELETE FROM %s
|
||||
WHERE TorrentID = ?
|
||||
', $table), $id
|
||||
);
|
||||
|
||||
$torrent = new \Gazelle\Torrent();
|
||||
$groupId = $torrent->idToGroup($id);
|
||||
$this->cache->delete_value('torrents_details_'.$groupId);
|
||||
}
|
||||
|
||||
public function missing(string $type, string $filter, string $search, int $limit, int $offset, int $userId) {
|
||||
$baseQuery = '';
|
||||
$columns = '';
|
||||
$joins = [];
|
||||
$where = [];
|
||||
$order = '';
|
||||
$params = [];
|
||||
$joinParams = [];
|
||||
|
||||
switch ($type) {
|
||||
case 'checksum':
|
||||
$columns = 't.ID AS TorrentID, t.GroupID';
|
||||
$baseQuery = '
|
||||
FROM torrents t
|
||||
INNER JOIN torrents_group tg ON (tg.ID = t.GroupID)
|
||||
INNER JOIN torrents_leech_stats tls ON (tls.TorrentID = t.ID)';
|
||||
$order = 'ORDER BY tls.Snatched DESC, t.Time ASC';
|
||||
$where[] = "t.HasLogDB = '1' AND t.LogChecksum = '0'";
|
||||
$mode = 'torrents';
|
||||
switch ($filter) {
|
||||
case 'snatched':
|
||||
$joins[] = 'INNER JOIN xbt_snatched as x ON x.fid = t.ID AND x.uid = ?';
|
||||
$joinParams[] = $userId;
|
||||
break;
|
||||
case 'uploaded':
|
||||
$where[] = 't.UserID = ?';
|
||||
$params[] = $userId;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'tags':
|
||||
case 'folders':
|
||||
case 'files':
|
||||
case 'lineage':
|
||||
$columns = 'bad.TorrentID, t.GroupID';
|
||||
$baseQuery = sprintf('
|
||||
FROM %s AS bad
|
||||
INNER JOIN torrents t ON (t.ID = bad.TorrentID)
|
||||
INNER JOIN torrents_group tg ON (tg.ID = t.GroupID)', $this->badMap[$type]);
|
||||
$order = 'ORDER BY bad.TimeAdded ASC';
|
||||
$mode = 'torrents';
|
||||
switch ($filter) {
|
||||
case 'snatched':
|
||||
$joins[] = 'INNER JOIN xbt_snatched x ON (x.fid = bad.TorrentID AND x.uid = ?)';
|
||||
$joinParams[] = $userId;
|
||||
break;
|
||||
case 'uploaded':
|
||||
$where[] = 't.UserID = ?';
|
||||
$params[] = $userId;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'artwork':
|
||||
$columns = 'tg.ID, tg.Name';
|
||||
$baseQuery = "
|
||||
FROM torrents_group tg
|
||||
LEFT JOIN wiki_torrents wt ON (wt.RevisionID = tg.RevisionID)
|
||||
LEFT JOIN torrent_group_has_attr tgha ON (tgha.TorrentGroupID = tg.ID
|
||||
AND tgha.TorrentGroupAttrID = (
|
||||
SELECT tga.ID FROM torrent_group_attr tga WHERE tga.Name = 'no-cover-art'
|
||||
)
|
||||
)";
|
||||
$where[] = "tg.CategoryID = 1 AND coalesce(wt.Image, tg.WikiImage) = '' AND tgha.TorrentGroupID IS NULL";
|
||||
$order = 'ORDER BY tg.Name';
|
||||
switch ($filter) {
|
||||
case 'snatched':
|
||||
$joins[] = '
|
||||
INNER JOIN
|
||||
(
|
||||
SELECT DISTINCT t.GroupID
|
||||
FROM torrents t
|
||||
INNER JOIN xbt_snatched x ON (x.fid = t.ID AND x.uid = ?)
|
||||
) s ON (s.GroupID = tg.ID)';
|
||||
$joinParams[] = $userId;
|
||||
break;
|
||||
case 'uploaded':
|
||||
$joins[] = '
|
||||
INNER JOIN
|
||||
(
|
||||
SELECT DISTINCT GroupID
|
||||
FROM torrents
|
||||
WHERE UserID = ?
|
||||
) u ON (u.GroupID = tg.ID)';
|
||||
$joinParams[] = $userId;
|
||||
break;
|
||||
}
|
||||
$mode = 'groups';
|
||||
break;
|
||||
case 'artistimg':
|
||||
$where[] = "(wa.Image IS NULL OR wa.Image = '')";
|
||||
$mode = 'artists';
|
||||
break;
|
||||
case 'artistdesc':
|
||||
$where[] = "(wa.Body IS NULL OR wa.Body = '')";
|
||||
$mode = 'artists';
|
||||
break;
|
||||
case 'artistdiscogs':
|
||||
$where[] = "(dg.artist_id IS NULL)";
|
||||
$mode = 'artists';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($mode === 'artists') {
|
||||
$columns = 'a.ArtistID, a.Name';
|
||||
$baseQuery = '
|
||||
FROM artists_group a
|
||||
LEFT JOIN wiki_artists wa ON (wa.RevisionID = a.RevisionID)
|
||||
LEFT JOIN artist_usage au ON (au.artist_id = a.ArtistID)';
|
||||
$order = 'ORDER BY coalesce(au.uses, 0) DESC, a.Name ASC';
|
||||
}
|
||||
|
||||
if ($search !== '') {
|
||||
switch ($mode) {
|
||||
case 'torrents':
|
||||
$where[] = '(
|
||||
tg.Name LIKE ?
|
||||
OR t.Description LIKE ?
|
||||
OR coalesce(wt.Body, tg.WikiBody) LIKE ?
|
||||
OR tg.TagList LIKE ?
|
||||
)';
|
||||
$searchString = "%$search%";
|
||||
$params = array_merge($params, array_fill(0, 4, $searchString));
|
||||
$joins[] = 'LEFT JOIN wiki_torrents wt ON (wt.RevisionID = tg.RevisionID)';
|
||||
break;
|
||||
case 'groups':
|
||||
$where[] = '(
|
||||
tg.Name LIKE ?
|
||||
OR coalesce(wt.Body, tg.WikiBody) LIKE ?
|
||||
OR tg.TagList LIKE ?
|
||||
)';
|
||||
$searchString = "%$search%";
|
||||
$params = array_merge($params, array_fill(0, 3, $searchString));
|
||||
break;
|
||||
case 'artists':
|
||||
$where[] = 'a.Name LIKE ?';
|
||||
$searchString = "%$search%";
|
||||
$params[] = $searchString;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($where) > 0) {
|
||||
$where = 'WHERE '.implode(' AND ', $where);
|
||||
} else {
|
||||
$where = '';
|
||||
}
|
||||
|
||||
|
||||
$joins = implode("\n", $joins);
|
||||
$params = array_merge($joinParams, $params);
|
||||
|
||||
$query = sprintf('
|
||||
SELECT count(*)
|
||||
%s
|
||||
%s
|
||||
%s', $baseQuery, $joins, $where
|
||||
);
|
||||
$resultCount = $this->db->scalar($query, ...$params);
|
||||
|
||||
$query = sprintf('
|
||||
SELECT %s
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
LIMIT %s OFFSET %s', $columns, $baseQuery, $joins, $where, $order, $limit, $offset
|
||||
);
|
||||
|
||||
$this->db->prepared_query($query, ...$params);
|
||||
|
||||
switch ($mode) {
|
||||
case 'torrents':
|
||||
if ($resultCount > 0) {
|
||||
$torrents = $this->db->to_array('TorrentID', MYSQLI_ASSOC);
|
||||
} else {
|
||||
$torrents = [];
|
||||
}
|
||||
$groups = \Torrents::get_groups(array_column($torrents, 'GroupID'));
|
||||
$results = array_map(function ($torrent) use ($groups) {
|
||||
return ['ID' => $torrent['TorrentID'], 'Group' => $groups[$torrent['GroupID']]];
|
||||
}, $torrents);
|
||||
break;
|
||||
case 'groups':
|
||||
if ($resultCount > 0) {
|
||||
$results = $this->db->to_array('ID', MYSQLI_ASSOC);
|
||||
foreach (\Artists::get_artists(array_keys($results)) as $groupId => $data) {
|
||||
$results[$groupId]['Artists'] = [];
|
||||
$results[$groupId]['ExtendedArtists'] = [];
|
||||
foreach ([1, 4, 6] as $importance) {
|
||||
if (isset($data[$importance])) {
|
||||
$results[$groupId]['Artists'] = array_merge($results[$groupId]['Artists'], $data[$importance]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$results = [];
|
||||
}
|
||||
break;
|
||||
case 'artists':
|
||||
if ($resultCount > 0) {
|
||||
$results = $this->db->to_array('ArtistID', MYSQLI_ASSOC);
|
||||
} else {
|
||||
$results = [];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return [$results, $resultCount, $mode];
|
||||
}
|
||||
|
||||
public function singleSeeded() {
|
||||
$this->db->prepared_query("
|
||||
SELECT t.ID, t.GroupID
|
||||
FROM torrents t
|
||||
INNER JOIN torrents_leech_stats tls On (t.ID = tls.TorrentID)
|
||||
WHERE t.Format = 'FLAC'
|
||||
AND tls.Seeders = 1
|
||||
ORDER BY t.LogScore DESC, rand()
|
||||
LIMIT 50
|
||||
"
|
||||
);
|
||||
|
||||
$torrents = $this->db->to_array('ID', MYSQLI_ASSOC);
|
||||
$groups = \Torrents::get_groups(array_column($torrents, 'GroupID'));
|
||||
return array_map(function ($torrent) use ($groups) {
|
||||
return ['ID' => $torrent['ID'], 'Group' => $groups[$torrent['GroupID']]];
|
||||
}, $torrents);
|
||||
}
|
||||
|
||||
public function twigGroups(array $results) {
|
||||
$releaseTypes = $this->releaseTypes;
|
||||
return array_reduce($results, function ($acc, $item) use ($releaseTypes) {
|
||||
$torrent = $item['ID'];
|
||||
$group = $item['Group'];
|
||||
$groupId = $group['ID'];
|
||||
$groupYear = $group['Year'];
|
||||
$groupName = $group['Name'];
|
||||
$groupFlags = isset($group['Flags']) ? $group['Flags'] : ['IsSnatched' => false];
|
||||
$groupTorrents = isset($group['Torrents']) ? $group['Torrents'] : [];
|
||||
$releaseType = $group['ReleaseType'];
|
||||
$tags = new \Tags($group['TagList']);
|
||||
$extendedArtists = $group['ExtendedArtists'];
|
||||
|
||||
if (!empty($extendedArtists[1]) || !empty($extendedArtists[4]) || !empty($extendedArtists[5]) || !empty($extendedArtists[6])) {
|
||||
unset($extendedArtists[2]);
|
||||
unset($extendedArtists[3]);
|
||||
$displayName = \Artists::display_artists($extendedArtists);
|
||||
} else {
|
||||
$displayName = '';
|
||||
}
|
||||
$displayName .= "<a href=\"torrents.php?id=$groupId&torrentid=$torrent#torrent$torrent\">$groupName";
|
||||
if ($groupYear > 0) {
|
||||
$displayName .= " [$groupYear]";
|
||||
}
|
||||
if ($releaseType > 0) {
|
||||
$displayName .= ' ['.$releaseTypes[$releaseType].']';
|
||||
}
|
||||
|
||||
$extraInfo = \Torrents::torrent_info($groupTorrents[$torrent]);
|
||||
if ($extraInfo) {
|
||||
$displayName .= " - $extraInfo";
|
||||
}
|
||||
|
||||
$displayName .= '</a>';
|
||||
|
||||
$acc[$torrent] = [
|
||||
'group_id' => $groupId,
|
||||
'snatched' => $groupTorrents[$torrent]['IsSnatched'] ?? false,
|
||||
'name' => $displayName,
|
||||
'tags' => $tags->format(),
|
||||
'token' => \Torrents::can_use_token($groupTorrents[$torrent]),
|
||||
'fl_message' => FL_confirmation_msg($groupTorrents[$torrent]['Seeders'], $groupTorrents[$torrent]['Size']),
|
||||
];
|
||||
return $acc;
|
||||
}, []);
|
||||
}
|
||||
|
||||
private $badMap = [
|
||||
'tags' => 'torrents_bad_tags',
|
||||
'folders' => 'torrents_bad_folders',
|
||||
'files' => 'torrents_bad_files',
|
||||
'lineage' => 'torrents_missing_lineage'
|
||||
];
|
||||
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
<?php
|
||||
$badMap = [
|
||||
'tags' => 'torrents_bad_tags',
|
||||
'folders' => 'torrents_bad_folders',
|
||||
'files' => 'torrents_bad_files',
|
||||
'lineage' => 'torrents_missing_lineage'
|
||||
];
|
||||
$attrTypes = ['tags', 'folders', 'files', 'lineage'];
|
||||
$filters = ['all', 'snatched', 'uploaded'];
|
||||
$types = ['checksum', 'tags', 'folders', 'files', 'lineage', 'artwork', 'artistimg', 'artistdesc', 'artistdiscogs'];
|
||||
|
||||
if (!empty($_GET['userid']) && is_number($_GET['userid'])) {
|
||||
if (check_perms('users_override_paranoia')) {
|
||||
@@ -16,357 +13,74 @@ if (!empty($_GET['userid']) && is_number($_GET['userid'])) {
|
||||
$userId = $LoggedUser['ID'];
|
||||
}
|
||||
|
||||
if (empty($_GET['type']) || !in_array($_GET['type'], ['checksum', 'tags', 'folders', 'files', 'lineage', 'artwork', 'artistimg', 'artistdesc', 'artistdiscogs'])) {
|
||||
$_GET['type'] = 'checksum';
|
||||
}
|
||||
$type = $_GET['type'];
|
||||
$filter = in_array($_GET['filter'] ?? '', $filters) ? $_GET['filter'] : $filters[0];
|
||||
$type = in_array($_GET['type'] ?? '', $types) ? $_GET['type'] : $types[0];
|
||||
$search = $_GET['search'] ?? '';
|
||||
|
||||
if (empty($_GET['filter']) || !in_array($_GET['filter'], ['snatched', 'uploaded'])) {
|
||||
$_GET['filter'] = 'all';
|
||||
}
|
||||
$filter = $_GET['filter'];
|
||||
$better = new \Gazelle\Manager\Better($ReleaseTypes);
|
||||
|
||||
if (empty($_GET['search'])) {
|
||||
$_GET['search'] = '';
|
||||
}
|
||||
$search = $_GET['search'];
|
||||
|
||||
if (check_perms('admin_reports') && in_array($type, array_keys($badMap)) && !empty($_GET['remove']) && is_number($_GET['remove'])) {
|
||||
$remove = $_GET['remove'];
|
||||
$DB->prepared_query(sprintf('
|
||||
DELETE FROM %s
|
||||
WHERE TorrentID = ?', $badMap[$type]), $remove);
|
||||
$DB->prepared_query('
|
||||
SELECT GroupID
|
||||
FROM torrents
|
||||
WHERE ID = ?', $remove);
|
||||
list($groupId) = $DB->next_record();
|
||||
$Cache->delete_value('torrents_details_'.$groupId);
|
||||
if (check_perms('admin_reports') && in_array($type, $attrTypes) && $remove = (int)($_GET['remove'] ?? 0)) {
|
||||
$better->removeAttribute($type, $remove);
|
||||
}
|
||||
|
||||
$query = '';
|
||||
$joins = [];
|
||||
$where = [];
|
||||
$order = '';
|
||||
$params = [];
|
||||
$joinparams = [];
|
||||
[$page, $limit, $offset] = \Gazelle\DB::pageLimit(TORRENTS_PER_PAGE);
|
||||
|
||||
switch ($type) {
|
||||
case 'checksum':
|
||||
$query = '
|
||||
SELECT SQL_CALC_FOUND_ROWS t.ID AS TorrentID, t.GroupID
|
||||
FROM torrents t
|
||||
INNER JOIN torrents_group tg ON tg.ID = t.GroupID';
|
||||
$order = 'ORDER BY t.Time ASC';
|
||||
$where[] = "t.HasLogDB = '1' AND t.LogChecksum = '0'";
|
||||
$mode = 'torrents';
|
||||
switch ($filter) {
|
||||
case 'snatched':
|
||||
$joins[] = 'INNER JOIN xbt_snatched as x ON x.fid = t.ID AND x.uid = ?';
|
||||
$joinparams[] = $userId;
|
||||
break;
|
||||
case 'uploaded':
|
||||
$where[] = 't.UserID = ?';
|
||||
$params[] = $userId;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'tags':
|
||||
case 'folders':
|
||||
case 'files':
|
||||
case 'lineage':
|
||||
$query = sprintf('
|
||||
SELECT SQL_CALC_FOUND_ROWS bad.TorrentID, t.GroupID
|
||||
FROM %s AS bad
|
||||
INNER JOIN torrents t ON t.ID = bad.TorrentID
|
||||
INNER JOIN torrents_group tg ON tg.ID = t.GroupID', $badMap[$type]);
|
||||
$order = 'ORDER BY bad.TimeAdded ASC';
|
||||
$mode = 'torrents';
|
||||
switch ($filter) {
|
||||
case 'snatched':
|
||||
$joins[] = 'INNER JOIN xbt_snatched as x ON x.fid = bad.TorrentID AND x.uid = ?';
|
||||
$joinparams[] = $userId;
|
||||
break;
|
||||
case 'uploaded':
|
||||
$where[] = 't.UserID = ?';
|
||||
$params[] = $userId;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'artwork':
|
||||
$query = '
|
||||
SELECT SQL_CALC_FOUND_ROWS tg.ID, tg.Name
|
||||
FROM torrents_group tg';
|
||||
$where[] = "tg.CategoryID = 1 AND coalesce(wt.Image, tg.WikiImage) = ''";
|
||||
$order = 'ORDER BY tg.Name';
|
||||
$joins[] = 'LEFT JOIN wiki_torrents wt ON wt.RevisionID = tg.RevisionID';
|
||||
$mode = 'groups';
|
||||
break;
|
||||
case 'artistimg':
|
||||
$query = '
|
||||
SELECT SQL_CALC_FOUND_ROWS a.ArtistID, a.Name
|
||||
FROM artists_group a';
|
||||
$where[] = "(wa.Image IS NULL OR wa.Image = '')";
|
||||
$order = 'ORDER BY a.Name';
|
||||
$joins[] = 'LEFT JOIN wiki_artists wa ON wa.RevisionID = a.RevisionID';
|
||||
$mode = 'artists';
|
||||
break;
|
||||
case 'artistdesc':
|
||||
$query = '
|
||||
SELECT SQL_CALC_FOUND_ROWS a.ArtistID, a.Name
|
||||
FROM artists_group a';
|
||||
$where[] = "(wa.Body IS NULL OR wa.Body = '')";
|
||||
$order = 'ORDER BY a.Name';
|
||||
$joins[] = 'LEFT JOIN wiki_artists wa ON wa.RevisionID = a.RevisionID';
|
||||
$mode = 'artists';
|
||||
break;
|
||||
case 'artistdiscogs':
|
||||
$query = '
|
||||
SELECT SQL_CALC_FOUND_ROWS a.ArtistID, a.Name
|
||||
FROM artists_group a';
|
||||
$where[] = "(dg.artist_id IS NULL)";
|
||||
$order = 'ORDER BY a.Name';
|
||||
$joins[] = 'LEFT JOIN artist_discogs dg ON dg.artist_id = a.ArtistID';
|
||||
$mode = 'artists';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($search !== '') {
|
||||
switch ($mode) {
|
||||
case 'torrents':
|
||||
$where[] = '(
|
||||
tg.Name LIKE ?
|
||||
OR t.Description LIKE ?
|
||||
OR coalesce(wt.Body, tg.WikiBody) LIKE ?
|
||||
OR tg.TagList LIKE ?
|
||||
)';
|
||||
$searchString = "%$search%";
|
||||
$params = array_merge($params, array_fill(0, 4, $searchString));
|
||||
$joins[] = 'LEFT JOIN wiki_torrents wt ON wt.RevisionID = tg.RevisionID';
|
||||
break;
|
||||
case 'groups':
|
||||
$where[] = '(
|
||||
tg.Name LIKE ?
|
||||
OR coalesce(wt.Body, tg.WikiBody) LIKE ?
|
||||
OR tg.TagList LIKE ?
|
||||
)';
|
||||
$searchString = "%$search%";
|
||||
$params = array_merge($params, array_fill(0, 3, $searchString));
|
||||
break;
|
||||
case 'artists':
|
||||
$where[] = 'a.Name LIKE ?';
|
||||
$searchString = "%$search%";
|
||||
$params = array_merge($params, [$searchString]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($where) > 0) {
|
||||
$where = 'WHERE '.implode(' AND ', $where);
|
||||
} else {
|
||||
$where = '';
|
||||
}
|
||||
|
||||
$page = !empty($_GET['page']) ? intval($_GET['page']) : 1;
|
||||
$page = max(1, $page);
|
||||
$limit = TORRENTS_PER_PAGE;
|
||||
$offset = TORRENTS_PER_PAGE * ($page - 1);
|
||||
|
||||
$joins = implode("\n", $joins);
|
||||
$params = array_merge($joinparams, $params);
|
||||
$query = sprintf('
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
%s LIMIT %s OFFSET %s', $query, $joins, $where, $order, $limit, $offset);
|
||||
|
||||
$qId = $DB->prepared_query($query, ...$params);
|
||||
$DB->prepared_query('SELECT FOUND_ROWS()');
|
||||
list($resultCount) = $DB->next_record();
|
||||
[$results, $resultCount, $mode] = $better->missing($type, $filter, $search, $limit, $offset, $userId);
|
||||
|
||||
$pages = Format::get_pages($page, $resultCount, TORRENTS_PER_PAGE);
|
||||
|
||||
switch ($mode) {
|
||||
case 'torrents':
|
||||
if ($resultCount > 0) {
|
||||
$DB->set_query_id($qId);
|
||||
$torrents = $DB->to_array('TorrentID', MYSQLI_ASSOC);
|
||||
} else {
|
||||
$torrents = [];
|
||||
}
|
||||
$groups = array_map(function ($t) { return $t['GroupID']; }, $torrents);
|
||||
$results = Torrents::get_groups($groups);
|
||||
break;
|
||||
case 'groups':
|
||||
if ($resultCount > 0) {
|
||||
$DB->set_query_id($qId);
|
||||
$groups = $DB->to_array('ID', MYSQLI_ASSOC);
|
||||
foreach (Artists::get_artists(array_keys($groups)) as $groupId => $data) {
|
||||
$groups[$groupId]['Artists'] = [];
|
||||
$groups[$groupId]['ExtendedArtists'] = [];
|
||||
foreach ([1, 4, 6] as $importance) {
|
||||
if (isset($data[$importance])) {
|
||||
$groups[$groupId]['Artists'] = array_merge($groups[$groupId]['Artists'], $data[$importance]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$groups = [];
|
||||
}
|
||||
break;
|
||||
case 'artists':
|
||||
if ($resultCount > 0) {
|
||||
$DB->set_query_id($qId);
|
||||
$artists = $DB->to_array('ArtistID', MYSQLI_ASSOC);
|
||||
} else {
|
||||
$artists = [];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
View::show_header('Missing Search');
|
||||
|
||||
function selected($val) {
|
||||
return $val ? ' selected="selected"' : '';
|
||||
}
|
||||
?>
|
||||
|
||||
<br />
|
||||
<div class="thin">
|
||||
<h2>Missing</h2>
|
||||
<div class="linkbox">
|
||||
<a class="brackets" href="better.php?method=transcode">Transcodes</a>
|
||||
<a class="brackets" href="better.php?method=missing">Missing</a>
|
||||
<a class="brackets" href="better.php?method=single">Single Seeded</a>
|
||||
</div>
|
||||
<form class="search_form" name="missing" action="" method="get">
|
||||
<input type="hidden" name="method" value="missing" />
|
||||
<table cellpadding="6" cellspacing="1" border="0" class="border" width="100%">
|
||||
<tr>
|
||||
<td class="label"><strong>Filter</strong></td>
|
||||
<td>
|
||||
<select name="type">
|
||||
<option value="checksum"<?=selected($type == 'checksum')?>>Missing Checksums</option>
|
||||
<option value="tags"<?=selected($type == 'tags')?>>Bad Tags</option>
|
||||
<option value="folders"<?=selected($type == 'folders')?>>Bad Folders</option>
|
||||
<option value="files"<?=selected($type == 'files')?>>Bad Files</option>
|
||||
<option value="lineage"<?=selected($type == 'lineage')?>>Missing Lineage</option>
|
||||
<option value="artwork"<?=selected($type == 'artwork')?>>Missing Artwork</option>
|
||||
<option value="artistimg"<?=selected($type == 'artistimg')?>>Missing Artist Images</option>
|
||||
<option value="artistdesc"<?=selected($type == 'artistdesc')?>>Missing Artist Descriptions</option>
|
||||
<option value="artistdiscogs"<?=selected($type == 'artistdiscogs')?>>Missing Artist Discogs ID</option>
|
||||
</select>
|
||||
<select name="filter">
|
||||
<option value="all"<?=selected($filter == 'all')?>>All</option>
|
||||
<option value="snatched"<?=selected($filter == 'snatched')?>>Snatched</option>
|
||||
<option value="uploaded"<?=selected($filter == 'uploaded')?>>Uploaded</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label"><strong>Search</strong></td>
|
||||
<td>
|
||||
<input type="search" name="search" size="60" value="<?=(!empty($_GET['search']) ? display_str($_GET['search']) : '')?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td> </td><td><input type="submit" value="Search" /></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="linkbox">
|
||||
<?=$pages?>
|
||||
</div>
|
||||
<div class="box pad">
|
||||
<div class="torrent">
|
||||
<h3>There are <?=$resultCount?> <?=$mode?> remaining<?php
|
||||
if ($mode == 'torrents' && count($torrents) > 1 && check_perms('zip_downloader')) {
|
||||
$idList = implode(',', array_map(function ($t) { return $t['TorrentID']; }, $torrents));
|
||||
?>
|
||||
<span class="torrents_links_block">
|
||||
<a class="brackets" href="torrents.php?action=collector&title=better&ids=<?=$idList?>" onclick="return confirm('If you do not have the content, your ratio WILL be affected; be sure to check the size of all torrents before downloading.');">Download All</a>
|
||||
</span>
|
||||
</h3>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<table width"=100%" class="torrent_table">
|
||||
<?php
|
||||
$filters = array_reduce($filters, function ($acc, $item) use ($filter) {
|
||||
$acc[$item] = $item === $filter;
|
||||
return $acc;
|
||||
}, []);
|
||||
|
||||
$types = array_reduce($types, function ($acc, $item) use ($type) {
|
||||
$acc[$item] = $item === $type;
|
||||
return $acc;
|
||||
}, []);
|
||||
|
||||
switch ($mode) {
|
||||
case 'torrents':
|
||||
foreach ($torrents as $torrent => $info) {
|
||||
$group = $results[$info['GroupID']];
|
||||
$groupId = $group['ID'];
|
||||
$groupYear = $group['Year'];
|
||||
$groupName = $group['Name'];
|
||||
$groupFlags = isset($group['Flags']) ? $group['Flags'] : ['IsSnatched' => false];
|
||||
$groupTorrents = isset($group['Torrents']) ? $group['Torrents'] : [];
|
||||
$releaseType = $group['ReleaseType'];
|
||||
$tags = new Tags($group['TagList']);
|
||||
$extendedArtists = $group['ExtendedArtists'];
|
||||
|
||||
if (!empty($extendedArtists[1]) || !empty($extendedArtists[4]) || !empty($extendedArtists[5]) || !empty($extendedArtists[6])) {
|
||||
unset($extendedArtists[2]);
|
||||
unset($extendedArtists[3]);
|
||||
$displayName = Artists::display_artists($extendedArtists);
|
||||
} else {
|
||||
$displayName = '';
|
||||
}
|
||||
$displayName .= "<a href=\"torrents.php?id=$groupId&torrentid=$torrent#torrent$torrent\" class=\"tooltip\" title=\"View torrent group\" dir=\"ltr\">$groupName</a>";
|
||||
if ($groupYear > 0) {
|
||||
$displayName .= " [$groupYear]";
|
||||
}
|
||||
if ($releaseType > 0) {
|
||||
$displayName .= ' ['.$ReleaseTypes[$releaseType].']';
|
||||
}
|
||||
|
||||
$extraInfo = Torrents::torrent_info($groupTorrents[$torrent]);
|
||||
if ($extraInfo) {
|
||||
$displayName .= " - $extraInfo";
|
||||
}
|
||||
?>
|
||||
<tr class="torrent torrent_row<?=$groupFlags['IsSnatched'] ? ' snatched_torrent"' : ''?>">
|
||||
<td>
|
||||
<span class="torrent_links_block">
|
||||
<a href="torrents.php?action=download&id=<?=$torrent?>&authkey=<?=$LoggedUser['AuthKey']?>&torrent_pass=<?=$LoggedUser['torrent_pass']?>" class="brackets tooltip" title="Download">DL</a>
|
||||
</span>
|
||||
<?=$displayName?>
|
||||
<?php if (check_perms('admin_reports')) { ?>
|
||||
<a href="better.php?method=missing&type=<?=$type?>&remove=<?=$torrent?>&filter=<?=$filter?>&search=<?=$search?>" class="brackets">X</a>
|
||||
<?php } ?>
|
||||
<div class="tags"><?=$tags->format()?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
case 'artists':
|
||||
$results = array_column($results, 'Name', 'ArtistID');
|
||||
break;
|
||||
case 'groups':
|
||||
foreach ($groups as $id => $group) {
|
||||
if (count($group['Artists']) > 1) {
|
||||
$results = array_reduce($results, function ($acc, $item) {
|
||||
if (count($item['Artists']) > 1) {
|
||||
$artist = 'Various Artists';
|
||||
} else {
|
||||
$artist = sprintf('<a href="artist.php?id=%s" target="_blank">%s</a>', $group['Artists'][0]['id'], $group['Artists'][0]['name']);
|
||||
$artist = sprintf('<a href="artist.php?id=%s" target="_blank">%s</a>', $item['Artists'][0]['id'], $item['Artists'][0]['name']);
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td><?=$artist?> - <a href="torrents.php?id=<?=$id?>" target="_blank"><?=$group['Name']?></a></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
$acc[$item['ID']] = ['artist' => $artist, 'name' => $item['Name']];
|
||||
return $acc;
|
||||
}, []);
|
||||
break;
|
||||
case 'artists':
|
||||
foreach ($artists as $id => $artist) {
|
||||
?>
|
||||
<tr>
|
||||
<td><a href="artist.php?id=<?=$id?>"><?=$artist['Name']?></a></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
case 'torrents':
|
||||
$results = $better->twigGroups($results);
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
echo G::$Twig->render('better/missing.twig', [
|
||||
'mode' => $mode,
|
||||
'results' => $results,
|
||||
'result_count' => $resultCount,
|
||||
'filters' => $filters,
|
||||
'search' => $search,
|
||||
'types' => $types,
|
||||
'auth_key' => $LoggedUser['AuthKey'],
|
||||
'torrent_pass' => $LoggedUser['torrent_pass'],
|
||||
'torrent_ids' => $mode !== 'torrents' ? null : implode(',', array_keys($results)),
|
||||
'pages' => $pages,
|
||||
'perms' => [
|
||||
'zip_downloader' => check_perms('zip_downloader'),
|
||||
'admin_reports' => check_perms('admin_reports'),
|
||||
],
|
||||
]);
|
||||
|
||||
View::show_footer();
|
||||
|
||||
@@ -1,80 +1,19 @@
|
||||
<?php
|
||||
if (($Results = $Cache->get_value('better_single_groupids')) === false) {
|
||||
$DB->query("
|
||||
SELECT
|
||||
t.ID AS TorrentID,
|
||||
t.GroupID AS GroupID
|
||||
FROM xbt_files_users AS x
|
||||
JOIN torrents AS t ON t.ID=x.fid
|
||||
WHERE t.Format='FLAC'
|
||||
GROUP BY x.fid
|
||||
HAVING COUNT(x.uid) = 1
|
||||
ORDER BY t.LogScore DESC, t.Time ASC
|
||||
LIMIT 30");
|
||||
|
||||
$Results = $DB->to_pair('GroupID', 'TorrentID', false);
|
||||
$Cache->cache_value('better_single_groupids', $Results, 30 * 60);
|
||||
}
|
||||
|
||||
$Groups = Torrents::get_groups(array_keys($Results));
|
||||
$better = new \Gazelle\Manager\Better($ReleaseTypes);
|
||||
$results = $better->twigGroups($better->singleSeeded());
|
||||
|
||||
View::show_header('Single seeder FLACs');
|
||||
?>
|
||||
<br />
|
||||
<div class="thin">
|
||||
<h2>Single Seeded</h2>
|
||||
<div class="linkbox">
|
||||
<a class="brackets" href="better.php?method=transcode">Transcodes</a>
|
||||
<a class="brackets" href="better.php?method=missing">Missing</a>
|
||||
<a class="brackets" href="better.php?method=single">Single Seeded</a>
|
||||
</div>
|
||||
<div class="box pad">
|
||||
<table width="100%" class="torrent_table">
|
||||
<tr class="colhead">
|
||||
<td>Torrent</td>
|
||||
</tr>
|
||||
<?php
|
||||
foreach ($Results as $GroupID => $FlacID) {
|
||||
if (!isset($Groups[$GroupID])) {
|
||||
continue;
|
||||
}
|
||||
$Group = $Groups[$GroupID];
|
||||
|
||||
if (!empty($Group['ExtendedArtists'][1]) || !empty($Group['ExtendedArtists'][4]) || !empty($Group['ExtendedArtists'][5]) || !empty($Group['ExtendedArtists'][6])) {
|
||||
unset($Group['ExtendedArtists'][2]);
|
||||
unset($Group['ExtendedArtists'][3]);
|
||||
$DisplayName = Artists::display_artists($Group['ExtendedArtists']);
|
||||
} else {
|
||||
$DisplayName = '';
|
||||
}
|
||||
echo G::$Twig->render('better/single.twig', [
|
||||
'results' => $results,
|
||||
'result_count' => count($results),
|
||||
'auth_key' => $LoggedUser['AuthKey'],
|
||||
'torrent_pass' => $LoggedUser['torrent_pass'],
|
||||
'tokens' => $LoggedUser['FLTokens'] > 0,
|
||||
'torrent_ids' => implode(',', array_keys($results)),
|
||||
'perms' => [
|
||||
'zip_downloader' => check_perms('zip_downloader'),
|
||||
],
|
||||
]);
|
||||
|
||||
$DisplayName .= "<a href=\"torrents.php?id=$GroupID&torrentid=$FlacID\" class=\"tooltip\" title=\"View torrent\" dir=\"ltr\">" . $Group['GroupName'] . '</a>';
|
||||
if ($Group['GroupYear'] > 0) {
|
||||
$DisplayName .= ' [' . $Group['GroupYear'] . ']';
|
||||
}
|
||||
if ($Group['ReleaseType'] > 0) {
|
||||
$DisplayName .= ' [' . $ReleaseTypes[$Group['ReleaseType']] . ']';
|
||||
}
|
||||
|
||||
$ExtraInfo = Torrents::torrent_info($Torrents[$FlacID]);
|
||||
if ($ExtraInfo) {
|
||||
$DisplayName .= ' - ' . $ExtraInfo;
|
||||
}
|
||||
$TorrentTags = new Tags($Group['TagList']);
|
||||
?>
|
||||
<tr class="torrent torrent_row<?=$Torrents[$FlacID]['IsSnatched'] ? ' snatched_torrent' : ''?>">
|
||||
<td>
|
||||
<span class="torrent_links_block">
|
||||
<a href="torrents.php?action=download&id=<?=$FlacID?>&authkey=<?=$LoggedUser['AuthKey']?>&torrent_pass=<?=$LoggedUser['torrent_pass']?>" title="Download" class="brackets tooltip">DL</a>
|
||||
</span>
|
||||
<?=$DisplayName?>
|
||||
<div class="tags"><?=$TorrentTags->format()?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} ?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
View::show_footer();
|
||||
|
||||
5
templates/better/links.twig
Normal file
5
templates/better/links.twig
Normal file
@@ -0,0 +1,5 @@
|
||||
<div class="linkbox">
|
||||
<a class="brackets" href="better.php?method=transcode">Transcodes</a>
|
||||
<a class="brackets" href="better.php?method=missing">Missing</a>
|
||||
<a class="brackets" href="better.php?method=single">Single Seeded</a>
|
||||
</div>
|
||||
73
templates/better/missing.twig
Normal file
73
templates/better/missing.twig
Normal file
@@ -0,0 +1,73 @@
|
||||
<br />
|
||||
<div class="thin">
|
||||
<h2>Missing</h2>
|
||||
{% include 'better/links.twig' only %}
|
||||
<form class="search_form" name="missing" action="" method="get">
|
||||
<input type="hidden" name="method" value="missing" />
|
||||
<table cellpadding="6" cellspacing="1" border="0" class="border" width="100%">
|
||||
<tr>
|
||||
<td class="label"><strong>Filter</strong></td>
|
||||
<td>
|
||||
<select name="type">
|
||||
<option value="checksum"{{ types.checksum | selected }}>Missing Checksums</option>
|
||||
<option value="tags"{{ types.tags | selected }}>Bad Tags</option>
|
||||
<option value="folders"{{ types.folders | selected }}>Bad Folders</option>
|
||||
<option value="files"{{ types.files | selected }}>Bad Files</option>
|
||||
<option value="lineage"{{ types.lineage | selected }}>Missing Lineage</option>
|
||||
<option value="artwork"{{ types.artwork | selected }}>Missing Artwork</option>
|
||||
<option value="artistimg"{{ types.artistimg | selected }}>Missing Artist Images</option>
|
||||
<option value="artistdesc"{{ types.artistdesc | selected }}>Missing Artist Descriptions</option>
|
||||
<option value="artistdiscogs"{{ types.artistdiscogs | selected }}>Missing Artist Discogs ID</option>
|
||||
</select>
|
||||
<select name="filter">
|
||||
<option value="all"{{ filters.all | selected }}>All</option>
|
||||
<option value="snatched"{{ filters.snatched | selected }}>Snatched</option>
|
||||
<option value="uploaded"{{ filters.uploaded | selected }}>Uploaded</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label"><strong>Search</strong></td>
|
||||
<td>
|
||||
<input type="search" name="search" size="60" value="{{ search }}" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td> </td><td><input type="submit" value="Search" /></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="linkbox">
|
||||
{{ pages | raw }}
|
||||
</div>
|
||||
<div class="box pad">
|
||||
<div class="torrent">
|
||||
<h3>There are {{ result_count }} {{ mode }} remaining
|
||||
{% if mode == 'torrents' and result_count > 1 and perms.zip_downloader %}
|
||||
{% include 'better/zip.twig' with {torrent_ids: torrent_ids} only %}
|
||||
{% endif %}
|
||||
</h3>
|
||||
</div>
|
||||
{% if mode is same as('torrents') %}
|
||||
{% include 'better/torrents.twig' with {results: results, auth_key: auth_key, torrent_pass: torrent_pass, tokens: tokens} only %}
|
||||
{% elseif mode is same as('groups') %}
|
||||
<table width"=100%" class="torrent_table">
|
||||
{% for id, group in results %}
|
||||
<tr>
|
||||
<td>{{ group.artist | raw }} - <a href="torrents.php?id={{ id }}" target="_blank">{{ group.name }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<table width"=100%" class="torrent_table">
|
||||
{% for id, name in results %}
|
||||
<tr>
|
||||
<td><a href="artist.php?id={{ id }}">{{ name }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="linkbox">
|
||||
{{ pages | raw }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
16
templates/better/single.twig
Normal file
16
templates/better/single.twig
Normal file
@@ -0,0 +1,16 @@
|
||||
<br />
|
||||
<div class="thin">
|
||||
<h2>Single Seeded</h2>
|
||||
{% include 'better/links.twig' only %}
|
||||
<div class="box pad">
|
||||
<div class="torrent">
|
||||
<h3>Here are {{ result_count }} random torrents
|
||||
{% if result_count > 0 and perms.zip_downloader %}
|
||||
{% include 'better/zip.twig' with {torrent_ids: torrent_ids} only %}
|
||||
{% endif %}
|
||||
</h3>
|
||||
</div>
|
||||
{% include 'better/torrents.twig' with {results: results, auth_key: auth_key, torrent_pass: torrent_pass, tokens: tokens} only %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
20
templates/better/torrents.twig
Normal file
20
templates/better/torrents.twig
Normal file
@@ -0,0 +1,20 @@
|
||||
<table width"=100%" class="torrent_table">
|
||||
{% for id, row in results %}
|
||||
<tr class="torrent torrent_row{{ row.snatched ? ' snatched_torrent' : '' }}">
|
||||
<td>
|
||||
<span class="torrent_links_block">
|
||||
<a href="torrents.php?action=download&id={{ id }}&authkey={{ auth_key }}&torrent_pass={{ torrent_pass }}" class="brackets tooltip" title="Download">DL</a>
|
||||
{% if row.token %}
|
||||
| <a href="torrents.php?action=download&id={{ id }}&authkey={{ auth_key }}&torrent_pass={{ torrent_pass }}&usetoken=1" class="brackets tooltip" title="Use a FL Token" onclick="return confirm('{{ row.fl_message }}');">FL</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
{{ row.name | raw }}
|
||||
{% if perms.admin_reports %}
|
||||
<a href="better.php?method=missing&type={{ type }}&remove={{ id }}&filter={{ filter }}&search={{ search }}" class="brackets">X</a>
|
||||
{% endif %}
|
||||
<div class="tags">{{ row.tags | raw }}</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
4
templates/better/zip.twig
Normal file
4
templates/better/zip.twig
Normal file
@@ -0,0 +1,4 @@
|
||||
<span class="torrents_links_block">
|
||||
<a class="brackets" href="torrents.php?action=collector&title=better&ids={{ torrent_ids }}" onclick="return confirm('If you do not have the content, your ratio WILL be affected; be sure to check the size of all torrents before downloading.');">Download All</a>
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user