mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-17 03:04:47 -05:00
251 lines
12 KiB
PHP
251 lines
12 KiB
PHP
<?php
|
|
|
|
namespace Gazelle\Manager;
|
|
|
|
use Gazelle\Request\Encoding;
|
|
use Gazelle\Request\Format;
|
|
use Gazelle\Request\Media;
|
|
use Gazelle\Request\LogCue;
|
|
use Gazelle\User;
|
|
|
|
class Request extends \Gazelle\BaseManager {
|
|
final public const ID_KEY = 'zz_r_%d';
|
|
|
|
public function create(
|
|
User $user,
|
|
int $bounty,
|
|
int $categoryId,
|
|
int $year,
|
|
string $title,
|
|
?string $image,
|
|
string $description,
|
|
string $recordLabel,
|
|
string $catalogueNumber,
|
|
int $releaseType,
|
|
Encoding $encoding,
|
|
Format $format,
|
|
Media $media,
|
|
LogCue $logCue,
|
|
string $oclc,
|
|
array $tagList = [],
|
|
int|null $groupId = null,
|
|
): \Gazelle\Request {
|
|
self::$db->prepared_query('
|
|
INSERT INTO requests (
|
|
LastVote, Visible, UserID, CategoryID, Title, Year, Image, Description, RecordLabel,
|
|
CatalogueNumber, ReleaseType, BitrateList, FormatList, MediaList, LogCue, Checksum, OCLC, GroupID)
|
|
VALUES (
|
|
now(), 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
$user->id, $categoryId, $title, $year, $image, $description, $recordLabel,
|
|
$catalogueNumber, $releaseType,
|
|
$encoding->dbValue(), $format->dbValue(), $media->dbValue(),
|
|
$logCue->dbValue(), $logCue->needLogChecksum ? 1 : 0, $oclc, $groupId
|
|
);
|
|
$request = new \Gazelle\Request(self::$db->inserted_id());
|
|
$this->pg()->prepared_query("
|
|
insert into request (
|
|
id_request, id_user, id_tgroup, id_category, id_release_type, year,
|
|
last_vote, created, modified,
|
|
description, title, image, catalogue_number, record_label,
|
|
log_score, need_log, need_cue, need_checksum,
|
|
artist_title_ts, encoding_str, format_str, media_str, tag
|
|
) values (
|
|
?, ?, ?, ?, ?, ?,
|
|
?, ?, ?,
|
|
?, ?, ?, ?, ?,
|
|
?, ?, ?, ?,
|
|
to_tsvector('simple', ?),
|
|
array[" . placeholders($encoding->dbList()) . "]::text[],
|
|
array[" . placeholders($format->dbList()) . "]::text[],
|
|
array[" . placeholders($media->dbList()) . "]::text[],
|
|
array[" . placeholders($tagList) . "]::int[]
|
|
)
|
|
", $request->id, $user->id, $groupId, $categoryId, $releaseType, $year,
|
|
$request->lastVoteDate(), $request->created(), $request->modified(),
|
|
$description, $title, $image, $catalogueNumber, $recordLabel,
|
|
$logCue->minScore, $logCue->needLog ? 't' : 'f', $logCue->needCue ? 't' : 'f', $logCue->needLogChecksum ? 't' : 'f',
|
|
$title, ...$encoding->dbList(), ...$format->dbList(), ...$media->dbList(), ...$tagList,
|
|
);
|
|
$request->vote($user, $bounty);
|
|
$request->artistFlush();
|
|
return $request;
|
|
}
|
|
|
|
public function findById(int $id): ?\Gazelle\Request {
|
|
$key = sprintf(self::ID_KEY, $id);
|
|
$requestId = self::$cache->get_value($key);
|
|
if ($requestId === false) {
|
|
$requestId = (int)self::$db->scalar("
|
|
SELECT ID FROM requests WHERE ID = ?
|
|
", $id
|
|
);
|
|
if ($requestId) {
|
|
self::$cache->cache_value($key, $requestId, 7200);
|
|
}
|
|
}
|
|
return $requestId ? new \Gazelle\Request($requestId) : null;
|
|
}
|
|
|
|
/**
|
|
* Find a list of unfilled requests by a user, sorted
|
|
* by most number of votes and then largest bounty
|
|
*
|
|
* @return array of \Gazelle\Request objects
|
|
*/
|
|
public function findUnfilledByUser(User $user, int $limit): array {
|
|
self::$db->prepared_query("
|
|
SELECT DISTINCT r.ID
|
|
FROM requests r
|
|
INNER JOIN requests_votes v ON (v.RequestID = r.ID)
|
|
WHERE r.TorrentID = 0
|
|
AND r.UserID = ?
|
|
GROUP BY r.ID
|
|
ORDER BY count(v.UserID) DESC, sum(v.Bounty) DESC
|
|
LIMIT 0, ?
|
|
", $user->id, $limit
|
|
);
|
|
return array_map(
|
|
fn ($id) => $this->findById($id),
|
|
self::$db->collect(0)
|
|
);
|
|
}
|
|
|
|
public function findByArtist(\Gazelle\Artist $artist): array {
|
|
$key = sprintf(\Gazelle\Artist::CACHE_REQUEST_ARTIST, $artist->id);
|
|
$requestList = self::$cache->get_value($key);
|
|
if ($requestList === false) {
|
|
self::$db->prepared_query("
|
|
SELECT DISTINCT r.ID
|
|
FROM requests AS r
|
|
INNER JOIN requests_votes v ON (v.RequestID = r.ID)
|
|
INNER JOIN requests_artists AS ra ON (ra.RequestID = r.ID)
|
|
INNER JOIN artists_alias aa ON (ra.AliasID = aa.AliasID)
|
|
WHERE r.TorrentID = 0
|
|
AND aa.ArtistID = ?
|
|
GROUP BY r.ID
|
|
ORDER BY count(v.UserID) DESC, sum(v.Bounty) DESC
|
|
", $artist->id
|
|
);
|
|
$requestList = self::$db->collect(0);
|
|
self::$cache->cache_value($key, $requestList, 3600);
|
|
}
|
|
return array_map(fn($id) => $this->findById($id), $requestList);
|
|
}
|
|
|
|
public function findByTGroup(\Gazelle\TGroup $tgroup): array {
|
|
$key = sprintf(\Gazelle\TGroup::CACHE_REQUEST_TGROUP, $tgroup->id);
|
|
$requestList = self::$cache->get_value($key);
|
|
if ($requestList === false) {
|
|
self::$db->prepared_query("
|
|
SELECT r.ID
|
|
FROM requests AS r
|
|
INNER JOIN torrents_group tg ON (tg.ID = r.GroupID)
|
|
WHERE r.TorrentID = 0
|
|
AND tg.ID = ?
|
|
ORDER BY r.TimeAdded ASC
|
|
", $tgroup->id
|
|
);
|
|
$requestList = self::$db->collect(0);
|
|
self::$cache->cache_value($key, $requestList, 3600);
|
|
}
|
|
return array_map(fn($id) => $this->findById($id), $requestList);
|
|
}
|
|
|
|
public function findByTorrentReported(\Gazelle\TorrentAbstract $torrent): array {
|
|
self::$db->prepared_query("
|
|
SELECT DISTINCT req.ID
|
|
FROM requests AS req
|
|
INNER JOIN reportsv2 AS rep ON (rep.TorrentID = req.TorrentID)
|
|
WHERE rep.Status != 'Resolved'
|
|
AND req.TorrentID = ?
|
|
", $torrent->id
|
|
);
|
|
return array_map(fn($id) => $this->findById($id), self::$db->collect(0));
|
|
}
|
|
|
|
public function relay(): int {
|
|
return $this->pg()->prepared_query("
|
|
merge into request r using (
|
|
with a_t as (
|
|
select rr.\"ID\" as id_request,
|
|
to_tsvector('simple', coalesce(string_agg(aa.\"Name\", ' '), '')
|
|
|| ' ' || rr.\"Title\"
|
|
) as artist_title_ts
|
|
from relay.requests rr
|
|
left join relay.requests_artists ra on (ra.\"RequestID\" = rr.\"ID\")
|
|
left join relay.artists_alias aa using (\"AliasID\")
|
|
left join relay.artist_role ar on (ar.artist_role_id = ra.artist_role_id)
|
|
where (ar.slug is null or ar.slug != 'guest')
|
|
and rr.updated >= (select coalesce(max(modified), '2000-01-01'::timestamptz) from request)
|
|
group by rr.\"ID\", rr.\"Title\"
|
|
),
|
|
tl as (
|
|
select rt.id_request,
|
|
array_agg(rt.id_tag) as tag
|
|
from request_tag rt
|
|
inner join relay.requests rr on (rr.\"ID\" = rt.id_request)
|
|
where rr.updated >= (select coalesce(max(modified), '2000-01-01'::timestamptz) from request)
|
|
group by rt.id_request
|
|
)
|
|
select
|
|
rr.\"ID\" as id_request, rr.\"UserID\" as id_user, rr.\"FillerID\" as id_filler,
|
|
rr.\"TorrentID\" as id_torrent, rr.\"GroupID\" as id_tgroup,
|
|
rr.\"CategoryID\" as id_category, rr.\"ReleaseType\" as id_release_type,
|
|
rr.\"Year\" as year, rr.\"LastVote\" as last_vote, rr.\"TimeFilled\" as filled,
|
|
rr.created, rr.updated + '1 microsecond'::interval as updated,
|
|
rr.\"Description\" as description, rr.\"Title\" as title, rr.\"Image\" as image,
|
|
rr.\"CatalogueNumber\" as catalogue_number, rr.\"RecordLabel\" as record_label,
|
|
(case when regexp_replace(coalesce(rr.\"LogCue\", ''), '\D+', '', 'g') = ''
|
|
then '0'
|
|
else regexp_replace(coalesce(rr.\"LogCue\", ''), '\D+', '', 'g')
|
|
end)::int as log_score,
|
|
coalesce(position('Log' in rr.\"LogCue\") > 0, false) as need_log,
|
|
coalesce(position('Cue' in rr.\"LogCue\") > 0, false) as need_cue,
|
|
case when rr.\"Checksum\" = 0 then false else true end as need_checksum,
|
|
a_t.artist_title_ts,
|
|
string_to_array(rr.\"BitrateList\", '|') as encoding_str,
|
|
string_to_array(rr.\"FormatList\", '|') as format_str,
|
|
string_to_array(rr.\"MediaList\", '|') as media_str,
|
|
coalesce(tl.tag, ARRAY[]::int[]) as tag
|
|
from relay.requests rr
|
|
inner join a_t on (a_t.id_request = rr.\"ID\")
|
|
left join tl on (tl.id_request = rr.\"ID\")
|
|
) as i on r.id_request = i.id_request
|
|
when not matched then
|
|
insert (
|
|
id_request, id_user, id_tgroup, id_category,
|
|
id_release_type, year,
|
|
last_vote, created, modified,
|
|
description, title, image, catalogue_number, record_label,
|
|
log_score, need_log, need_cue, need_checksum,
|
|
artist_title_ts, tag, encoding_str, format_str, media_str
|
|
) values (
|
|
i.id_request, i.id_user, i.id_tgroup, i.id_category,
|
|
i.id_release_type, i.year,
|
|
i.last_vote, i.created, i.updated,
|
|
i.description, i.title, i.image, i.catalogue_number, i.record_label,
|
|
i.log_score, i.need_log, i.need_cue, i.need_checksum,
|
|
i.artist_title_ts,
|
|
i.tag,
|
|
string_to_array(i.encoding_str::text, '|'),
|
|
string_to_array(i.format_str::text, '|'),
|
|
string_to_array(i.media_str::text, '|')
|
|
)
|
|
when matched then
|
|
update set
|
|
filled = i.filled, id_filler = i.id_filler, id_torrent = i.id_torrent,
|
|
id_user = i.id_user, id_tgroup = i.id_tgroup, id_category = i.id_category,
|
|
id_release_type = i.id_release_type, year = i.year,
|
|
last_vote = i.last_vote, created = i.created, modified = i.updated,
|
|
description = i.description, title = i.title, image = i.image,
|
|
catalogue_number = i.catalogue_number, record_label = i.record_label,
|
|
log_score = i.log_score, need_log = i.need_log,
|
|
need_cue = i.need_cue, need_checksum = i.need_checksum,
|
|
artist_title_ts = i.artist_title_ts, tag = i.tag,
|
|
encoding_str = string_to_array(i.encoding_str::text, '|'),
|
|
format_str = string_to_array(i.format_str::text, '|'),
|
|
media_str = string_to_array(i.media_str::text, '|')
|
|
");
|
|
}
|
|
}
|