mirror of
https://github.com/YGGverse/YGGtracker.git
synced 2025-01-22 12:44:25 +00:00
implement torrent search features
This commit is contained in:
parent
e9375f9127
commit
8ab4c0b9cf
@ -3,29 +3,146 @@
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
use App\Service\UserService;
|
||||
use App\Service\PageService;
|
||||
use App\Service\TorrentService;
|
||||
|
||||
class SearchController extends AbstractController
|
||||
{
|
||||
#[Route(
|
||||
'/{_locale}/search',
|
||||
name: 'search_index'
|
||||
name: 'search_index',
|
||||
methods:
|
||||
[
|
||||
'GET'
|
||||
]
|
||||
)]
|
||||
public function index(Request $request): Response
|
||||
public function index(
|
||||
Request $request,
|
||||
UserService $userService,
|
||||
PageService $pageService,
|
||||
TorrentService $torrentService
|
||||
): Response
|
||||
{
|
||||
$query = $request->query->get('query');
|
||||
// Init user
|
||||
$user = $userService->init(
|
||||
$request->getClientIp()
|
||||
);
|
||||
|
||||
return $this->render('default/search/index.html.twig', [
|
||||
'query' => $query
|
||||
]);
|
||||
$page = $request->query->get('page') ? (int) $request->query->get('page') : 1;
|
||||
|
||||
switch ($request->query->get('type'))
|
||||
{
|
||||
case 'page':
|
||||
|
||||
break;
|
||||
case 'torrent':
|
||||
|
||||
$torrents = [];
|
||||
foreach ($torrentService->searchTorrents($request->query->get('query')) as $torrent)
|
||||
{
|
||||
// Read file
|
||||
if (!$file = $torrentService->readTorrentFileByTorrentId($torrent->getId()))
|
||||
{
|
||||
continue; // @TODO
|
||||
}
|
||||
|
||||
// Generate keywords
|
||||
$keywords = [];
|
||||
$query = explode(' ', mb_strtolower($request->query->get('query')));
|
||||
foreach (explode(',', $torrent->getKeywords()) as $keyword)
|
||||
{
|
||||
if (in_array($keyword, $query))
|
||||
{
|
||||
$keywords[] = urlencode($keyword);
|
||||
}
|
||||
}
|
||||
|
||||
$torrents[] =
|
||||
[
|
||||
'id' => $torrent->getId(),
|
||||
'added' => $torrent->getAdded(),
|
||||
'file' =>
|
||||
[
|
||||
'name' => $file->getName(),
|
||||
'size' => $file->getSize(),
|
||||
],
|
||||
'scrape' =>
|
||||
[
|
||||
'seeders' => (int) $torrent->getSeeders(),
|
||||
'peers' => (int) $torrent->getPeers(),
|
||||
'leechers' => (int) $torrent->getLeechers(),
|
||||
],
|
||||
'user' =>
|
||||
[
|
||||
'id' => $torrent->getUserId(),
|
||||
'identicon' => $userService->identicon(
|
||||
$userService->getUser(
|
||||
$torrent->getUserId()
|
||||
)->getAddress()
|
||||
)
|
||||
],
|
||||
'keywords' => $keywords,
|
||||
'download' =>
|
||||
[
|
||||
'file' =>
|
||||
[
|
||||
'exist' => (bool) $torrentService->findTorrentDownloadFile(
|
||||
$torrent->getId(),
|
||||
$user->getId()
|
||||
),
|
||||
'total' => $torrentService->findTorrentDownloadFilesTotalByTorrentId(
|
||||
$torrent->getId()
|
||||
)
|
||||
],
|
||||
'magnet' =>
|
||||
[
|
||||
'exist' => (bool) $torrentService->findTorrentDownloadMagnet(
|
||||
$torrent->getId(),
|
||||
$user->getId()
|
||||
),
|
||||
'total' => $torrentService->findTorrentDownloadMagnetsTotalByTorrentId(
|
||||
$torrent->getId()
|
||||
)
|
||||
]
|
||||
],
|
||||
'star' =>
|
||||
[
|
||||
'exist' => (bool) $torrentService->findTorrentStar(
|
||||
$torrent->getId(),
|
||||
$user->getId()
|
||||
),
|
||||
'total' => $torrentService->findTorrentStarsTotalByTorrentId(
|
||||
$torrent->getId()
|
||||
)
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('default/search/torrent.html.twig', [
|
||||
'query' => $request->query->get('query'),
|
||||
'torrents' => $torrents
|
||||
]);
|
||||
|
||||
break;
|
||||
default:
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
public function module(string $query = ''): Response
|
||||
public function module(
|
||||
?string $query,
|
||||
?string $type
|
||||
): Response
|
||||
{
|
||||
return $this->render('default/search/module.html.twig', [
|
||||
'query' => $query,
|
||||
'type' => $type,
|
||||
]);
|
||||
}
|
||||
}
|
@ -6,7 +6,9 @@ use App\Repository\TorrentRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
// @TODO #[ORM\Index(columns: ['keywords'], name: 'keywords_idx', flags: ['fulltext'])]
|
||||
#[ORM\Entity(repositoryClass: TorrentRepository::class)]
|
||||
|
||||
class Torrent
|
||||
{
|
||||
#[ORM\Id]
|
||||
|
@ -20,4 +20,21 @@ class TorrentRepository extends ServiceEntityRepository
|
||||
{
|
||||
parent::__construct($registry, Torrent::class);
|
||||
}
|
||||
|
||||
public function searchByKeywords(
|
||||
array $keywords
|
||||
): ?array
|
||||
{
|
||||
$query = $this->createQueryBuilder('t');
|
||||
|
||||
foreach ($keywords as $keyword)
|
||||
{
|
||||
$query->orWhere('t.keywords LIKE :query')
|
||||
->setParameter('query', "%{$keyword}%");
|
||||
}
|
||||
|
||||
return $query->orderBy('t.id', 'ASC') // same as t.added
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
}
|
||||
|
@ -246,11 +246,11 @@ class TorrentService
|
||||
}
|
||||
|
||||
// Torrent
|
||||
public function getTorrent(int $id): ?Torrent
|
||||
public function getTorrent(int $torrentId): ?Torrent
|
||||
{
|
||||
return $this->entityManagerInterface
|
||||
->getRepository(Torrent::class)
|
||||
->find($id);
|
||||
->find($torrentId);
|
||||
}
|
||||
|
||||
public function addTorrent(
|
||||
@ -285,6 +285,15 @@ class TorrentService
|
||||
);
|
||||
}
|
||||
|
||||
public function searchTorrents(string $query) : array
|
||||
{
|
||||
return $this->entityManagerInterface
|
||||
->getRepository(Torrent::class)
|
||||
->searchByKeywords(
|
||||
explode(' ', $query)
|
||||
);
|
||||
}
|
||||
|
||||
public function setTorrentsApprovedByUserId(
|
||||
int $userId,
|
||||
bool $value
|
||||
|
@ -1,2 +0,0 @@
|
||||
{% extends 'default/layout.html.twig' %}
|
||||
{% block title %}{{ query }} - {{'Search'|trans }} - {{ name }}{% endblock %}
|
@ -12,5 +12,5 @@
|
||||
<option value="page">{{ 'Pages' | trans }}</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
<input type="submit" value="{{ 'Search' | trans }}" />
|
||||
<input {% if query %}class="button-green"{% endif %} type="submit" value="{{ 'Search' | trans }}" />
|
||||
</form>
|
138
templates/default/search/torrent.html.twig
Normal file
138
templates/default/search/torrent.html.twig
Normal file
@ -0,0 +1,138 @@
|
||||
{% extends 'default/layout.html.twig' %}
|
||||
{% block title %}{% if query %}{{ query }}{% else %}{{ 'New' | trans }}{% endif %} - {{ 'Torrents' | trans }} - {{ name }}{% endblock %}
|
||||
{% block main_content %}
|
||||
{% if torrents %}
|
||||
{% for torrent in torrents %}
|
||||
<div class="padding-24-px margin-y-8-px border-radius-3-px background-color-night">
|
||||
<a name="{{ torrent.id }}"></a>
|
||||
<div class="margin-b-16-px">
|
||||
<h2>
|
||||
<a class="text-color-default" href="{{ path('torrent_info', { torrentId : torrent.id }) }}">
|
||||
{{ torrent.file.name }}
|
||||
</a>
|
||||
</h2>
|
||||
{% if torrent.scrape.leechers == 0 and torrent.scrape.leechers == 0 %}
|
||||
<span class="label label-green margin-x-4-px font-size-10-px position-relative top--2 cursor-default"
|
||||
title="{{ 'Active leechers waiting for seeders' | trans }}">
|
||||
{{ 'wanted' | trans }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if torrent.keywords %}
|
||||
<div class="margin-b-16-px">
|
||||
{% for keyword in torrent.keywords %}
|
||||
<a href="{{ path('search_index', { query : keyword, type : 'torrent' }) }}">
|
||||
#{{ keyword }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="margin-b-16-px border-bottom-default"></div>
|
||||
{#
|
||||
<sup>
|
||||
{{ torrent.added | format_ago }}
|
||||
{{ 'by' | trans }}
|
||||
<a href="{{ path('user_info', { userId : torrent.user.id }) }}">
|
||||
<img class="border-radius-50 border-color-default vertical-align-middle margin-x-4-px" src="{{ torrent.user.identicon }}" alt="{{ 'identicon' | trans }}" />
|
||||
</a>
|
||||
</sup>
|
||||
#}
|
||||
<span class="margin-r-4-px cursor-default" title="{{ 'Size' | trans }}">
|
||||
<sup>
|
||||
{{ torrent.file.size | format_bytes }}
|
||||
</sup>
|
||||
</span>
|
||||
<span class="margin-r-4-px cursor-default opacity-0 parent-hover-opacity-09" title="{{ 'Seeders' | trans }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5z"/>
|
||||
</svg>
|
||||
<sup>
|
||||
{{ torrent.scrape.seeders }}
|
||||
</sup>
|
||||
</span>
|
||||
<span class="margin-r-4-px cursor-default opacity-0 parent-hover-opacity-09" title="{{ 'Peers' | trans }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z"/>
|
||||
</svg>
|
||||
<sup>
|
||||
{{ torrent.scrape.peers }}
|
||||
</sup>
|
||||
</span>
|
||||
<span class="margin-r-4-px cursor-default opacity-0 parent-hover-opacity-09" title="{{ 'Leechers' | trans }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M.5 6a.5.5 0 0 0-.488.608l1.652 7.434A2.5 2.5 0 0 0 4.104 16h5.792a2.5 2.5 0 0 0 2.44-1.958l.131-.59a3 3 0 0 0 1.3-5.854l.221-.99A.5.5 0 0 0 13.5 6H.5ZM13 12.5a2.01 2.01 0 0 1-.316-.025l.867-3.898A2.001 2.001 0 0 1 13 12.5ZM2.64 13.825 1.123 7h11.754l-1.517 6.825A1.5 1.5 0 0 1 9.896 15H4.104a1.5 1.5 0 0 1-1.464-1.175Z"/>
|
||||
<path d="m4.4.8-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 3.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 3.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 3 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 4.4.8Zm3 0-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 6.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 6.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 6 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 7.4.8Zm3 0-.003.004-.014.019a4.077 4.077 0 0 0-.204.31 2.337 2.337 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.198 3.198 0 0 1-.202.388 5.385 5.385 0 0 1-.252.382l-.019.025-.005.008-.002.002A.5.5 0 0 1 9.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 9.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 9 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 10.4.8Z"/>
|
||||
</svg>
|
||||
<sup>
|
||||
{{ torrent.scrape.leechers }}
|
||||
</sup>
|
||||
</span>
|
||||
<div class="float-right">
|
||||
<a class="margin-l-8-px margin-r-4-px" href="{{ path('torrent_download_magnet', {torrentId : torrent.id}) }}" title="{{ 'Open magnet link' | trans }}">
|
||||
{% if torrent.download.magnet.exist %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M15 12h-4v3h4v-3ZM5 12H1v3h4v-3ZM0 8a8 8 0 1 1 16 0v8h-6V8a2 2 0 1 0-4 0v8H0V8Z"/>
|
||||
</svg>
|
||||
{% else %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M8 1a7 7 0 0 0-7 7v3h4V8a3 3 0 0 1 6 0v3h4V8a7 7 0 0 0-7-7Zm7 11h-4v3h4v-3ZM5 12H1v3h4v-3ZM0 8a8 8 0 1 1 16 0v8h-6V8a2 2 0 1 0-4 0v8H0V8Z"/>
|
||||
</svg>
|
||||
{% endif %}
|
||||
</a>
|
||||
<sup class="cursor-default" title="{{ 'Total' | trans }}">
|
||||
{{ torrent.download.magnet.total }}
|
||||
</sup>
|
||||
<a class="margin-l-8-px margin-r-4-px" href="{{ path('torrent_download_file', {torrentId : torrent.id}) }}" title="{{ 'Download torrent file' | trans }}">
|
||||
{% if torrent.download.file.exist %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
|
||||
</svg>
|
||||
{% else %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
|
||||
</svg>
|
||||
{% endif %}
|
||||
</a>
|
||||
<sup class="cursor-default" title="{{ 'Total' | trans }}">
|
||||
{{ torrent.download.file.total }}
|
||||
</sup>
|
||||
<a class="margin-l-8-px margin-r-4-px" href="{{ path('torrent_star_toggle', {torrentId : torrent.id}) }}" title="{{ 'Star' | trans }}">
|
||||
{% if torrent.star.exist %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>
|
||||
</svg>
|
||||
{% else %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356-.83 4.73zm4.905-2.767-3.686 1.894.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957-3.686-1.894a.503.503 0 0 0-.461 0z"/>
|
||||
</svg>
|
||||
{% endif %}
|
||||
</a>
|
||||
<sup class="cursor-default" title="{{ 'Total' | trans }}">
|
||||
{{ torrent.star.total }}
|
||||
</sup>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="padding-24-px margin-y-8-px border-radius-3-px background-color-night">
|
||||
<div class="text-center">
|
||||
<h1 class="display-block margin-b-16-px">
|
||||
{{ 'Nothing found' | trans }}
|
||||
</h1>
|
||||
<div class="text-color-night margin-y-16-px">
|
||||
{{ '* share new torrent file to change it' | trans }}
|
||||
</div>
|
||||
<form name="submit" method="get" action="{{ path('page_submit') }}">
|
||||
<button class="button-green margin-y-8-px" type="submit">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3v-3z"/>
|
||||
</svg>
|
||||
<span class="margin-x-4-px">
|
||||
{{ 'Submit' | trans }}
|
||||
</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
Loading…
x
Reference in New Issue
Block a user