mirror of
https://github.com/sigmasternchen/MyTube
synced 2025-03-15 21:08:55 +00:00
link constraints work now
This commit is contained in:
parent
db66c98976
commit
417e60b296
7 changed files with 136 additions and 17 deletions
|
@ -62,7 +62,7 @@ class DashboardController extends AbstractController
|
||||||
|
|
||||||
foreach ($videos as $video) {
|
foreach ($videos as $video) {
|
||||||
$video->setCustomId($this->uuidMapper->toString($video->getId()));
|
$video->setCustomId($this->uuidMapper->toString($video->getId()));
|
||||||
$video->setViews($this->loggingService->getViews($video));
|
$video->setViews($this->loggingService->getViewsVideo($video));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render("dashboard/dashboard.html.twig", [
|
return $this->render("dashboard/dashboard.html.twig", [
|
||||||
|
|
|
@ -54,7 +54,7 @@ class WatchController extends AbstractController
|
||||||
$this->uuidMapper = $uuidMapper;
|
$this->uuidMapper = $uuidMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isAllowed(?Video $video, VideoLink $link): int
|
private function isAllowed(?Video $video, VideoLink $link, bool $strict): int
|
||||||
{
|
{
|
||||||
if (!$link) {
|
if (!$link) {
|
||||||
return self::NOT_ALLOWED;
|
return self::NOT_ALLOWED;
|
||||||
|
@ -66,10 +66,14 @@ class WatchController extends AbstractController
|
||||||
|
|
||||||
// TODO: check constraints
|
// TODO: check constraints
|
||||||
|
|
||||||
|
if (!$link->viewable($strict)) {
|
||||||
|
return self::NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
return self::ALLOWED;
|
return self::ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkRequestData($videoId, $linkId): array
|
private function checkRequestData($videoId, $linkId, bool $strict = true): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$video = $this->videoService->get($this->uuidMapper->fromString($videoId));
|
$video = $this->videoService->get($this->uuidMapper->fromString($videoId));
|
||||||
|
@ -84,7 +88,7 @@ class WatchController extends AbstractController
|
||||||
|
|
||||||
if (!$allowed) {
|
if (!$allowed) {
|
||||||
$link = $this->videoLinkService->get($this->uuidMapper->fromString($linkId));
|
$link = $this->videoLinkService->get($this->uuidMapper->fromString($linkId));
|
||||||
$allowed = $this->isAllowed($video, $link);
|
$allowed = $this->isAllowed($video, $link, $strict);
|
||||||
}
|
}
|
||||||
} catch (ConversionException $e) {
|
} catch (ConversionException $e) {
|
||||||
throw new AccessDeniedHttpException();
|
throw new AccessDeniedHttpException();
|
||||||
|
@ -122,7 +126,7 @@ class WatchController extends AbstractController
|
||||||
*/
|
*/
|
||||||
public function qualityPlaylist($videoId, $linkId, int $quality): Response
|
public function qualityPlaylist($videoId, $linkId, int $quality): Response
|
||||||
{
|
{
|
||||||
$data = $this->checkRequestData($videoId, $linkId);
|
$data = $this->checkRequestData($videoId, $linkId, false);
|
||||||
|
|
||||||
$file = self::CONTENT_RELATIVE . self::CONTENT_DIRECTORY . $data["video"]->getId() . "/" . $quality . "p/" . "playlist.m3u8";
|
$file = self::CONTENT_RELATIVE . self::CONTENT_DIRECTORY . $data["video"]->getId() . "/" . $quality . "p/" . "playlist.m3u8";
|
||||||
|
|
||||||
|
@ -137,7 +141,7 @@ class WatchController extends AbstractController
|
||||||
*/
|
*/
|
||||||
public function tsFile($videoId, $linkId, int $quality, int $tsFileId): Response
|
public function tsFile($videoId, $linkId, int $quality, int $tsFileId): Response
|
||||||
{
|
{
|
||||||
$data = $this->checkRequestData($videoId, $linkId);
|
$data = $this->checkRequestData($videoId, $linkId, false);
|
||||||
|
|
||||||
$file = self::CONTENT_RELATIVE . self::CONTENT_DIRECTORY . $data["video"]->getId() . "/" . $quality . "p/" . sprintf(self::TS_FILE_FORMAT, $tsFileId);
|
$file = self::CONTENT_RELATIVE . self::CONTENT_DIRECTORY . $data["video"]->getId() . "/" . $quality . "p/" . sprintf(self::TS_FILE_FORMAT, $tsFileId);
|
||||||
|
|
||||||
|
@ -199,7 +203,7 @@ class WatchController extends AbstractController
|
||||||
}
|
}
|
||||||
|
|
||||||
$data["video"]->setCustomId($videoId);
|
$data["video"]->setCustomId($videoId);
|
||||||
$data["video"]->setViews($this->loggingService->getViews($data["video"]));
|
$data["video"]->setViews($this->loggingService->getViewsVideo($data["video"]));
|
||||||
|
|
||||||
return $this->render("watch/watch.html.twig", [
|
return $this->render("watch/watch.html.twig", [
|
||||||
"viewToken" => $viewToken,
|
"viewToken" => $viewToken,
|
||||||
|
|
|
@ -38,6 +38,7 @@ class VideoLink
|
||||||
* @ORM\Column(type="integer", nullable=true)
|
* @ORM\Column(type="integer", nullable=true)
|
||||||
*/
|
*/
|
||||||
private $maxViews;
|
private $maxViews;
|
||||||
|
private $viewsLeft;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hours
|
* hours
|
||||||
|
@ -45,6 +46,7 @@ class VideoLink
|
||||||
* @ORM\Column(type="integer", nullable=true)
|
* @ORM\Column(type="integer", nullable=true)
|
||||||
*/
|
*/
|
||||||
private $viewableFor;
|
private $viewableFor;
|
||||||
|
private $viewableForLeft;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="datetime", nullable=true)
|
* @ORM\Column(type="datetime", nullable=true)
|
||||||
|
@ -159,4 +161,50 @@ class VideoLink
|
||||||
$this->customId = $customId;
|
$this->customId = $customId;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getViewableForLeft(): ?int
|
||||||
|
{
|
||||||
|
return $this->viewableForLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setViewableForLeft($viewableForLeft): self
|
||||||
|
{
|
||||||
|
$this->viewableForLeft = $viewableForLeft;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getViewsLeft(): ?int
|
||||||
|
{
|
||||||
|
return $this->viewsLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setViewsLeft($viewsLeft): self
|
||||||
|
{
|
||||||
|
$this->viewsLeft = $viewsLeft;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function viewable(bool $strict = true): bool
|
||||||
|
{
|
||||||
|
if ($this->getMaxViews()) {
|
||||||
|
if ($strict && $this->getViewsLeft() <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!$strict && $this->getViewsLeft() < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($this->getViewableFor()) {
|
||||||
|
if ($this->getViewableForLeft() && $this->getViewableForLeft() < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($this->getViewableUntil()) {
|
||||||
|
if ($this->getViewableUntil()->getTimestamp() < (new DateTime())->getTimestamp()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Repository;
|
namespace App\Repository;
|
||||||
|
|
||||||
use App\Entity\Video;
|
use App\Entity\Video;
|
||||||
|
use App\Entity\VideoLink;
|
||||||
use App\Entity\View;
|
use App\Entity\View;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
@ -63,10 +64,34 @@ class ViewRepository extends ServiceEntityRepository
|
||||||
public function countForVideo(Video $video): int
|
public function countForVideo(Video $video): int
|
||||||
{
|
{
|
||||||
$qb = $this->createQueryBuilder("v");
|
$qb = $this->createQueryBuilder("v");
|
||||||
return $qb->select("count(v.id)")
|
return $qb
|
||||||
->andWhere("v.video = :video")
|
->select("count(v.id)")
|
||||||
|
->where("v.video = :video")
|
||||||
->setParameter("video", $video->getId()->getBytes())
|
->setParameter("video", $video->getId()->getBytes())
|
||||||
->andWhere($qb->expr()->isNotNull("v.validated"))
|
->andWhere($qb->expr()->isNotNull("v.validated"))
|
||||||
->getQuery()->getSingleScalarResult();
|
->getQuery()->getSingleScalarResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function countForLink(VideoLink $videoLink): int
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder("v");
|
||||||
|
return $qb
|
||||||
|
->select("count(v.id)")
|
||||||
|
->where("v.link = :link")
|
||||||
|
->setParameter("link", $videoLink->getId()->getBytes())
|
||||||
|
->andWhere($qb->expr()->isNotNull("v.validated"))
|
||||||
|
->getQuery()->getSingleScalarResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFirstViewOfLink(VideoLink $videoLink): ?View
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder("v");
|
||||||
|
return $qb
|
||||||
|
->where("v.link = :link")
|
||||||
|
->setParameter("link", $videoLink->getId()->getBytes())
|
||||||
|
->andWhere($qb->expr()->isNotNull("v.validated"))
|
||||||
|
->orderBy("v.validated", "ASC")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getQuery()->getOneOrNullResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,9 +55,18 @@ class LoggingService
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getViews(Video $video): int
|
public function getViewsVideo(Video $video): int
|
||||||
{
|
{
|
||||||
//return $this->viewRepository->countByVideoAndNotNullValidated($video);
|
|
||||||
return $this->viewRepository->countForVideo($video);
|
return $this->viewRepository->countForVideo($video);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getViewsLink(VideoLink $videoLink)
|
||||||
|
{
|
||||||
|
return $this->viewRepository->countForLink($videoLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFirstView(VideoLink $videoLink)
|
||||||
|
{
|
||||||
|
return $this->viewRepository->getFirstViewOfLink($videoLink);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,24 +7,51 @@ namespace App\Service;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Entity\VideoLink;
|
use App\Entity\VideoLink;
|
||||||
use App\Repository\VideoLinkRepository;
|
use App\Repository\VideoLinkRepository;
|
||||||
|
use DateTime;
|
||||||
|
|
||||||
class VideoLinkService
|
class VideoLinkService
|
||||||
{
|
{
|
||||||
private $videoLinkRepository;
|
private $videoLinkRepository;
|
||||||
|
private $loggingService;
|
||||||
|
|
||||||
public function __construct(VideoLinkRepository $videoLinkRepository)
|
public function __construct(
|
||||||
|
VideoLinkRepository $videoLinkRepository,
|
||||||
|
LoggingService $loggingService
|
||||||
|
)
|
||||||
{
|
{
|
||||||
$this->videoLinkRepository = $videoLinkRepository;
|
$this->videoLinkRepository = $videoLinkRepository;
|
||||||
|
$this->loggingService = $loggingService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function evaluate(VideoLink $videoLink): VideoLink
|
||||||
|
{
|
||||||
|
if ($videoLink->getMaxViews()) {
|
||||||
|
$tmp = $this->loggingService->getViewsLink($videoLink);
|
||||||
|
$videoLink->setViewsLeft($videoLink->getMaxViews() - $tmp);
|
||||||
|
}
|
||||||
|
if ($videoLink->getViewableFor()) {
|
||||||
|
$tmp = $this->loggingService->getFirstView($videoLink);
|
||||||
|
if ($tmp) {
|
||||||
|
$videoLink->setViewableForLeft(
|
||||||
|
$videoLink->getViewableFor() -
|
||||||
|
($tmp->getTimestamp()->getTimestamp() - (new DateTime())->getTimestamp()) / 3600
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $videoLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get($linkId): ?VideoLink
|
public function get($linkId): ?VideoLink
|
||||||
{
|
{
|
||||||
return $this->videoLinkRepository->findOneById($linkId);
|
return $this->evaluate($this->videoLinkRepository->findOneById($linkId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAll(User $user): array
|
public function getAll(User $user): array
|
||||||
{
|
{
|
||||||
return $this->videoLinkRepository->findByCreator($user);
|
return array_map(function ($videoLink) {
|
||||||
|
return $this->evaluate($videoLink);
|
||||||
|
}, $this->videoLinkRepository->findByCreator($user));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add($videoLink): void
|
public function add($videoLink): void
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
<td>
|
<td>
|
||||||
<input type="checkbox">
|
<input type="checkbox">
|
||||||
</td>
|
</td>
|
||||||
|
<td></td>
|
||||||
<th>
|
<th>
|
||||||
Video
|
Video
|
||||||
</th>
|
</th>
|
||||||
|
@ -39,6 +40,11 @@
|
||||||
<td>
|
<td>
|
||||||
<input type="checkbox">
|
<input type="checkbox">
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if not link.viewable() %}
|
||||||
|
<i class="fas fa-exclamation-circle"></i>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ path("app_watch_page", {
|
<a href="{{ path("app_watch_page", {
|
||||||
linkId: constant("App\\Controller\\WatchController::OWNER_LINK_ID"),
|
linkId: constant("App\\Controller\\WatchController::OWNER_LINK_ID"),
|
||||||
|
@ -59,21 +65,21 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if link.viewableUntil %}
|
{% if link.viewableUntil %}
|
||||||
{{ viewableUntil | date("Y-m-d") }}
|
{{ link.viewableUntil | date("Y-m-d") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
-
|
-
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if link.maxViews %}
|
{% if link.maxViews %}
|
||||||
# / {{ link.maxViews }}
|
{{ link.viewsLeft }} / {{ link.maxViews }}
|
||||||
{% else %}
|
{% else %}
|
||||||
-
|
-
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if link.viewableFor %}
|
{% if link.viewableFor %}
|
||||||
# / {{ link.viewableFor }}
|
{{ link.viewableForLeft != null ? link.viewableForLeft : "-" }} / {{ link.viewableFor }}
|
||||||
{% else %}
|
{% else %}
|
||||||
-
|
-
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
Loading…
Reference in a new issue