link constraints work now

This commit is contained in:
overflowerror 2021-01-07 23:04:45 +01:00
parent db66c98976
commit 417e60b296
7 changed files with 136 additions and 17 deletions

View file

@ -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", [

View file

@ -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,

View file

@ -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;
}
} }

View file

@ -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();
}
} }

View file

@ -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);
}
} }

View file

@ -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

View file

@ -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 %}