/**
  * Execute the console command.
  *
  * @return mixed
  */
 public function fire()
 {
     if (!DebugHelpers::shouldSiteBeLive()) {
         $this->info('Not running because site should not be live at the moment.');
         return;
     }
     $this->info('Looking for media items which contain VOD which has just gone live.');
     // media items which have vod which is accessible, have the sent_vod_available_email flag set to 0, and have not had a email about this sent recently
     $mediaItems = DB::transaction(function () {
         $mediaItemsWantingEmail = array();
         $mediaItems = MediaItem::with("emailTasksMediaItem", "liveStreamItem")->accessible()->whereHas("videoItem", function ($q) {
             $q->live();
         })->where("email_notifications_enabled", true)->where("sent_vod_available_email", false)->lockForUpdate()->get();
         foreach ($mediaItems as $a) {
             // set the flag to say that this has been looked at and an email will probably be sent.
             $a->sent_vod_available_email = true;
             $a->save();
             $emailSentRecently = $a->emailTasksMediaItem()->where("created_at", ">=", Carbon::now()->subMinutes(15))->count() > 0;
             if ($emailSentRecently) {
                 continue;
             }
             $mediaItemsWantingEmail[] = $a;
             $emailTask = new EmailTasksMediaItem(array("message_type_id" => EmailHelpers::getMessageTypeIds()['availableNow']));
             // create an entry in the tasks table for the emails that are going to be sent
             $a->emailTasksMediaItem()->save($emailTask);
         }
         return $mediaItemsWantingEmail;
     });
     foreach ($mediaItems as $a) {
         $this->info("Building and sending email for media item with id " . $a->id . " and name \"" . $a->name . "\" which has VOD which has now gone live.");
         $title = null;
         $message = null;
         $liveStreamItem = $a->liveStreamItem;
         $hasBeenLive = !is_null($liveStreamItem) && $liveStreamItem->isOver();
         if ($hasBeenLive) {
             $title = "Did you miss our live show?";
             $message = "Watch it now on our website.";
         } else {
             $title = "New content available!";
             $message = "We now have new content available to watch on demand at our website.";
         }
         EmailHelpers::sendMediaItemEmail($a, '"{title}" Available Now From LA1:TV', $title, $message);
         $this->info("Sent email to users.");
     }
     $this->info("Finished.");
 }
Exemplo n.º 2
0
 public function postAdminStreamControlInfoMsg($id)
 {
     Auth::getUser()->hasPermissionOr401(Config::get("permissions.mediaItems"), 1);
     $mediaItem = MediaItem::with("liveStreamItem", "liveStreamItem.stateDefinition")->find($id);
     if (is_null($mediaItem)) {
         App::abort(404);
     }
     $liveStreamItem = $mediaItem->liveStreamItem;
     if (is_null($liveStreamItem)) {
         App::abort(404);
     }
     $requestedInfoMsg = null;
     if (isset($_POST['info_msg'])) {
         $requestedInfoMsg = $_POST['info_msg'];
     }
     if ($requestedInfoMsg === "") {
         $requestedInfoMsg = null;
     }
     if (!is_null($requestedInfoMsg) && strlen($requestedInfoMsg) <= 500) {
         $liveStreamItem->information_msg = $requestedInfoMsg;
         $liveStreamItem->save();
     } else {
         if (is_null($requestedInfoMsg)) {
             $liveStreamItem->information_msg = null;
             $liveStreamItem->save();
         }
     }
     $resp = array("infoMsg" => $liveStreamItem->information_msg);
     return Response::json($resp);
 }
 private function updateMediaItemsIndex()
 {
     $entries = ["toAdd" => [], "toRemove" => []];
     // in a transaction to make sure that version number that is returned is not one that
     // has been increased during a transaction which is stil in progress
     // mysql transaction isolation level should be REPEATABLE READ which will ensure that
     // the version number that is returned is the old one if it's currently being updated somewhere else,
     // until the update that is happening somewhere else is complete.
     $changedMediaItems = DB::transaction(function () {
         return MediaItem::with("playlists", "playlists.show")->needsReindexing()->get();
     });
     foreach ($changedMediaItems as $mediaItem) {
         if ($mediaItem->getIsAccessible()) {
             $entries["toAdd"][] = ["model" => $mediaItem, "data" => $this->getMediaItemData($mediaItem, $this->coverArtWidth, $this->coverArtHeight)];
         } else {
             // this item is no longer accessible so remove it from the index
             $entries["toRemove"][] = ["model" => $mediaItem];
         }
     }
     $this->syncIndexType("mediaItem", new MediaItem(), $entries);
 }
Exemplo n.º 4
0
 public function getIndex()
 {
     if (Config::get("degradedService.enabled")) {
         $view = View::make("home.degradedIndex");
         $view->contactEmail = Config::get("contactEmails.development");
         $this->setContent($view, "home", "home-degraded", array(), null, 200, array());
         return;
     }
     $promoMediaItem = MediaItem::with("liveStreamItem", "liveStreamItem.liveStream", "videoItem")->accessible()->whereNotNull("time_promoted")->orderBy("time_promoted", "desc")->first();
     if (!is_null($promoMediaItem)) {
         $liveStreamItem = $promoMediaItem->liveStreamItem;
         if (!is_null($liveStreamItem) && !$liveStreamItem->getIsAccessible()) {
             $liveStreamItem = null;
         }
         $videoItem = $promoMediaItem->videoItem;
         if (!is_null($videoItem) && !$videoItem->getIsAccessible()) {
             $videoItem = null;
         }
         $shouldShowItem = false;
         // if there is a live stream which is in the "not live" state the player won't display the vod
         // even if there is one. It will show the countdown to the start of the live stream.
         if (is_null($liveStreamItem) || !$liveStreamItem->isNotLive()) {
             if (!is_null($videoItem) && $videoItem->getIsLive()) {
                 $shouldShowItem = true;
             } else {
                 if (!is_null($liveStreamItem) && $liveStreamItem->hasWatchableContent()) {
                     $shouldShowItem = true;
                 }
             }
         }
         if (!$shouldShowItem) {
             $promoMediaItem = null;
         }
     }
     $promoPlaylist = null;
     if (!is_null($promoMediaItem)) {
         $promoPlaylist = $promoMediaItem->getDefaultPlaylist();
     }
     $promotedItems = MediaItem::getCachedPromotedItems();
     $promotedItemsData = array();
     // if there is an item to promote insert it at the start of the carousel
     if (!is_null($promoMediaItem)) {
         $coverArtResolutions = Config::get("imageResolutions.coverArt");
         $isLiveShow = !is_null($promoMediaItem->liveStreamItem) && !$promoMediaItem->liveStreamItem->isOver();
         $liveNow = $isLiveShow && $promoMediaItem->liveStreamItem->isLive();
         $promotedItemsData[] = array("coverArtUri" => $promoPlaylist->getMediaItemCoverArtUri($promoMediaItem, $coverArtResolutions['full']['w'], $coverArtResolutions['full']['h']), "name" => $promoMediaItem->name, "seriesName" => !is_null($promoPlaylist->show) ? $promoPlaylist->generateName() : null, "availableMsg" => $liveNow ? "Live Now!" : $this->buildTimeStr($isLiveShow, $promoMediaItem->scheduled_publish_time), "uri" => $promoPlaylist->getMediaItemUri($promoMediaItem));
     }
     foreach ($promotedItems as $a) {
         $mediaItem = $a['mediaItem'];
         if (!is_null($promoMediaItem) && intval($mediaItem->id) === intval($promoMediaItem->id)) {
             // prevent duplicate
             continue;
         }
         $isLiveShow = !is_null($mediaItem->liveStreamItem) && !$mediaItem->liveStreamItem->isOver();
         $liveNow = $isLiveShow && $mediaItem->liveStreamItem->isLive();
         $promotedItemsData[] = array("coverArtUri" => $a['coverArtUri'], "name" => $mediaItem->name, "seriesName" => $a['seriesName'], "availableMsg" => $liveNow ? "Live Now!" : $this->buildTimeStr($isLiveShow, $mediaItem->scheduled_publish_time), "uri" => $a['uri']);
     }
     $coverArtResolutions = Config::get("imageResolutions.coverArt");
     $recentlyAddedItems = MediaItem::getCachedRecentItems();
     $recentlyAddedTableData = array();
     foreach ($recentlyAddedItems as $i => $a) {
         $mediaItem = $a['mediaItem'];
         $recentlyAddedTableData[] = array("uri" => $a['uri'], "active" => false, "title" => $mediaItem->name, "escapedDescription" => null, "playlistName" => $a['playlistName'], "episodeNo" => $i + 1, "thumbnailUri" => $a['coverArtUri'], "thumbnailFooter" => null, "duration" => $a['duration']);
     }
     $mostPopularItems = MediaItem::getCachedMostPopularItems();
     $mostPopularTableData = array();
     foreach ($mostPopularItems as $i => $a) {
         $mediaItem = $a['mediaItem'];
         $mostPopularTableData[] = array("uri" => $a['uri'], "active" => false, "title" => $mediaItem->name, "escapedDescription" => null, "playlistName" => $a['playlistName'], "episodeNo" => $i + 1, "thumbnailUri" => $a['coverArtUri'], "thumbnailFooter" => null, "duration" => $a['duration']);
     }
     $view = View::make("home.index");
     $view->promotedItemsData = $promotedItemsData;
     $view->recentlyAddedPlaylistFragment = count($recentlyAddedTableData) > 0 ? View::make("fragments.home.playlist", array("stripedTable" => true, "headerRowData" => null, "tableData" => $recentlyAddedTableData)) : null;
     $view->mostPopularPlaylistFragment = count($mostPopularTableData) > 0 ? View::make("fragments.home.playlist", array("stripedTable" => true, "headerRowData" => null, "tableData" => $mostPopularTableData)) : null;
     $view->twitterWidgetId = Config::get("twitter.timeline_widget_id");
     $hasPromoItem = !is_null($promoMediaItem);
     $showPromoItem = $hasPromoItem;
     if ($hasPromoItem) {
         // determine if the user has already seen the promo
         $cookieVal = Cookie::get('seenPromo-' . $promoMediaItem->id);
         if (!is_null($cookieVal) && $cookieVal === $promoMediaItem->time_promoted->timestamp) {
             // user already seen promo
             $showPromoItem = false;
         }
         // put a cookie in the users browser to inform us in the future that the user has seen this promo video
         // store the time so that if the item is repromoted in the future, it will be shown again.
         Cookie::queue('seenPromo-' . $promoMediaItem->id, $promoMediaItem->time_promoted->timestamp, 40320);
         // store for 4 weeks
     }
     $view->showPromoItem = $showPromoItem;
     if ($showPromoItem) {
         $userHasMediaItemsPermission = false;
         if (Auth::isLoggedIn()) {
             $userHasMediaItemsPermission = Auth::getUser()->hasPermission(Config::get("permissions.mediaItems"), 0);
         }
         $view->promoPlayerInfoUri = PlayerHelpers::getInfoUri($promoPlaylist->id, $promoMediaItem->id);
         $view->promoRegisterWatchingUri = PlayerHelpers::getRegisterWatchingUri($promoPlaylist->id, $promoMediaItem->id);
         $view->promoRegisterLikeUri = PlayerHelpers::getRegisterLikeUri($promoPlaylist->id, $promoMediaItem->id);
         $view->promoAdminOverrideEnabled = $userHasMediaItemsPermission;
         $view->promoLoginRequiredMsg = "Please log in to use this feature.";
     }
     $this->setContent($view, "home", "home", array(), null, 200, array());
 }
 public function generateMediaItemsResponseData($limit, $sortMode, $sortDirection, $vodIncludeSetting, $streamIncludeSetting, $showStreamUris, $showVodUris)
 {
     $maxLimit = Config::get("api.mediaItemsMaxRetrieveLimit");
     if ($limit > $maxLimit) {
         $limit = $maxLimit;
     }
     $mediaItems = null;
     if ($sortMode === "POPULARITY") {
         if ($sortDirection === "ASC") {
             throw new Exception("ASC sort direction not supported for POPULARITY sort mode.");
         } else {
             if ($sortDirection === "DESC") {
                 // intentional
             } else {
                 throw new Exception("Invalid sort direction.");
             }
         }
         $items = MediaItem::getCachedMostPopularItems();
         $allMediaItems = array_column($items, 'mediaItem');
         $mediaItems = [];
         foreach ($allMediaItems as $a) {
             $includeVod = null;
             if ($vodIncludeSetting === "VOD_OPTIONAL") {
                 // intentional
             } else {
                 if ($vodIncludeSetting === "HAS_VOD") {
                     $includeVod = !is_null($a->videoItem) && $a->videoItem->getIsAccessible();
                 } else {
                     if ($vodIncludeSetting === "HAS_AVAILABLE_VOD") {
                         $includeVod = !is_null($a->videoItem) && $a->getIsAccessible() && $a->videoItem->getIsLive();
                     } else {
                         throw new Exception("Invalid vod include setting.");
                     }
                 }
             }
             $includeStream = null;
             if ($streamIncludeSetting === "STREAM_OPTIONAL") {
                 // intentional
             } else {
                 if ($streamIncludeSetting === "HAS_STREAM") {
                     $includeStream = !is_null($a->liveStreamItem) && $a->liveStreamItem->getIsAccessible();
                 } else {
                     if ($streamIncludeSetting === "HAS_LIVE_STREAM") {
                         $includeStream = !is_null($a->liveStreamItem) && $a->liveStreamItem->getIsAccessible() && $a->liveStreamItem->isLive();
                     } else {
                         throw new Exception("Invalid stream include setting.");
                     }
                 }
             }
             if (is_null($includeStream) && is_null($includeVod) || $includeStream || $includeVod) {
                 $mediaItems[] = $a;
             }
         }
     } else {
         if ($sortMode === "SCHEDULED_PUBLISH_TIME") {
             $mediaItems = MediaItem::with("liveStreamItem", "liveStreamItem.stateDefinition", "liveStreamItem.liveStream", "videoItem", "videoItem.sourceFile.vodData")->accessible();
             $mediaItems = $mediaItems->where(function ($q) use(&$vodIncludeSetting, &$streamIncludeSetting) {
                 if ($vodIncludeSetting === "VOD_OPTIONAL") {
                     // intentional
                 } else {
                     if ($vodIncludeSetting === "HAS_VOD") {
                         $q->whereHas("videoItem", function ($q2) {
                             $q2->accessible();
                         });
                     } else {
                         if ($vodIncludeSetting === "HAS_AVAILABLE_VOD") {
                             $q->whereHas("videoItem", function ($q2) {
                                 $q2->live();
                             });
                         } else {
                             throw new Exception("Invalid vod include setting.");
                         }
                     }
                 }
                 if ($streamIncludeSetting === "STREAM_OPTIONAL") {
                     // intentional
                 } else {
                     if ($streamIncludeSetting === "HAS_STREAM") {
                         $q->orWhereHas("liveStreamItem", function ($q2) {
                             $q2->accessible();
                         });
                     } else {
                         if ($streamIncludeSetting === "HAS_LIVE_STREAM") {
                             $q->orWhereHas("liveStreamItem", function ($q2) {
                                 $q2->live();
                             });
                         } else {
                             throw new Exception("Invalid stream include setting.");
                         }
                     }
                 }
             });
             $sortAsc = null;
             if ($sortDirection === "ASC") {
                 $sortAsc = true;
             } else {
                 if ($sortDirection === "DESC") {
                     $sortAsc = false;
                 } else {
                     throw new Exception("Invalid sort direction.");
                 }
             }
             $mediaItems = $mediaItems->orderBy("media_items.scheduled_publish_time", $sortAsc ? "asc" : "desc")->orderBy("id", "asc")->take($limit)->get()->all();
         } else {
             throw new Exception("Invalid sort mode.");
         }
     }
     $mediaItemsAndPlaylists = [];
     foreach ($mediaItems as $a) {
         $mediaItemsAndPlaylists[] = [null, $a];
     }
     $data = ["mediaItems" => $this->mediaItemTransformer->transformCollection($mediaItemsAndPlaylists, $this->getMediaItemTransformerOptions($showStreamUris, $showVodUris))];
     return new ApiResponseData($data);
 }
Exemplo n.º 6
0
 public function getIndex($dayGroupOffset = 0)
 {
     $dayGroupOffset = intval($dayGroupOffset);
     $daysPerPage = intval(Config::get("guide.daysPerPage"));
     $numPages = intval(Config::get("guide.numPages"));
     if (abs($dayGroupOffset) > $numPages) {
         App::abort(404);
     }
     $dayOffset = $dayGroupOffset * $daysPerPage;
     $startDate = Carbon::now()->startOfDay()->addDays($dayOffset);
     $endDate = Carbon::now()->startOfDay()->addDays($dayOffset + $daysPerPage);
     $mediaItems = MediaItem::with("liveStreamItem")->accessible()->scheduledPublishTimeBetweenDates($startDate, $endDate)->orderBy("scheduled_publish_time", "asc")->orderBy("name", "asc")->orderBy("description", "asc")->get();
     // of form ("dateStr", "mediaItems")
     $calendarData = array();
     $previousMediaItem = null;
     $lastDate = $startDate;
     foreach ($mediaItems as $a) {
         if (is_null($previousMediaItem) || $previousMediaItem->scheduled_publish_time->startOfDay()->timestamp !== $a->scheduled_publish_time->startOfDay()->timestamp) {
             // new day
             $calendarData[] = array("dateStr" => $this->getDateString($a->scheduled_publish_time->startOfDay()), "mediaItems" => array());
             $lastDate = $a->scheduled_publish_time->startOfDay();
         }
         $calendarData[count($calendarData) - 1]['mediaItems'][] = $a;
         $previousMediaItem = $a;
     }
     $coverArtResolutions = Config::get("imageResolutions.coverArt");
     $viewCalendarData = array();
     foreach ($calendarData as $day) {
         $playlistTableData = array();
         foreach ($day['mediaItems'] as $i => $item) {
             $playlist = $item->getDefaultPlaylist();
             $thumbnailUri = Config::get("custom.default_cover_uri");
             if (!Config::get("degradedService.enabled")) {
                 $thumbnailUri = $playlist->getMediaItemCoverArtUri($item, $coverArtResolutions['thumbnail']['w'], $coverArtResolutions['thumbnail']['h']);
             }
             $playlistName = null;
             if (!is_null($playlist->show)) {
                 // the current item in the playlist is part of a show.
                 $playlistName = $playlist->generateName();
             }
             $isLive = !is_null($item->liveStreamItem) && $item->liveStreamItem->getIsAccessible();
             $playlistTableData[] = array("uri" => $playlist->getMediaItemUri($item), "title" => $playlist->generateEpisodeTitle($item), "escapedDescription" => !is_null($item->description) ? e($item->description) : null, "playlistName" => $playlistName, "episodeNo" => null, "thumbnailUri" => $thumbnailUri, "thumbnailFooter" => array("isLive" => $isLive, "dateTxt" => $item->scheduled_publish_time->format("H:i")), "active" => false);
         }
         $playlistFragment = View::make("fragments.home.playlist", array("stripedTable" => false, "headerRowData" => null, "tableData" => $playlistTableData));
         $viewCalendarData[] = array("dateStr" => $day['dateStr'], "playlistFragment" => $playlistFragment);
     }
     $twitterProperties = array();
     $twitterProperties[] = array("name" => "card", "content" => "summary");
     $openGraphProperties = array();
     $description = "View a schedule of our upcoming content and also content you may have missed.";
     $twitterProperties[] = array("name" => "description", "content" => str_limit($description, 197, "..."));
     $openGraphProperties[] = array("name" => "og:description", "content" => $description);
     $title = "Guide";
     $twitterProperties[] = array("name" => "title", "content" => $title);
     $openGraphProperties[] = array("name" => "og:title", "content" => $title);
     $view = View::make("home.guide.index");
     $view->calendarData = $viewCalendarData;
     $view->titleDatesStr = $this->getDateString($startDate) . " - " . $this->getDateString((new Carbon($endDate))->subDays(1));
     $view->previousPageUri = $dayGroupOffset !== -1 * $numPages ? URL::route("guide", array($dayGroupOffset - 1)) : null;
     $view->previousPageStartDateStr = $this->getDateString($startDate->subDays($daysPerPage));
     $view->nextPageUri = $dayGroupOffset !== $numPages ? URL::route("guide", array($dayGroupOffset + 1)) : null;
     $view->nextPageStartDateStr = $this->getDateString($endDate);
     $this->setContent($view, "guide", "guide", $openGraphProperties, $title, 200, $twitterProperties);
 }
Exemplo n.º 7
0
 public function postComments($mediaItemId)
 {
     $mediaItem = MediaItem::with("comments", "comments.siteUser")->accessible()->find($mediaItemId);
     if (is_null($mediaItem)) {
         App::abort(404);
     }
     if (!$mediaItem->comments_enabled) {
         App::abort(403);
         // forbidden
     }
     // X = a number of comments
     // id = the id of the comment to start at. -1 means return the last X comments. loadLaterComments must be false in this case
     // load_later_comments = if true return all comments from the specified id otherwise load comments before it.
     // the id that is provided isn't checked to be valid as the comment it points too may have been deleted.
     $id = FormHelpers::getValue("id");
     $loadLaterComments = FormHelpers::getValue("load_later_comments") === "1";
     $id = !is_null($id) ? intval($id) : null;
     if (is_null($id)) {
         throw new Exception("Id must be set.");
     } else {
         if ($id === -1 && $loadLaterComments) {
             throw new Exception("If the id is -1 then load_later_comments must be false.");
         }
     }
     $commentsModels = null;
     $more = null;
     if ($loadLaterComments) {
         $commentsModels = $mediaItem->comments()->orderBy("id", "asc")->where("id", ">=", $id)->limit(Config::get("comments.number_to_retrieve") + 1)->get();
         $more = $commentsModels->count() === Config::get("comments.number_to_retrieve") + 1;
         if ($more) {
             $commentsModels->pop();
         }
     } else {
         $commentsModels = $mediaItem->comments()->orderBy("id", "desc");
         if ($id !== -1) {
             $commentsModels = $commentsModels->where("id", "<=", $id);
         }
         $commentsModels = $commentsModels->limit(Config::get("comments.number_to_retrieve") + 1)->get();
         $more = $commentsModels->count() === Config::get("comments.number_to_retrieve") + 1;
         if ($more) {
             $commentsModels->pop();
         }
         $commentsModels = $commentsModels->reverse();
         // get in ascending order
     }
     // true if a user is logged into the cms and has permission to manage comments and post as station.
     $userHasCommentsPermission = Auth::isLoggedIn() && Auth::getUser()->hasPermission(Config::get("permissions.siteComments"), 0);
     $comments = array();
     foreach ($commentsModels as $a) {
         // should not be returning supplied id
         if ($id !== -1 && intval($a->id) === $id) {
             continue;
         }
         $siteUser = $a->siteUser;
         $permissionToDelete = $userHasCommentsPermission || Facebook::isLoggedIn() && !is_null($siteUser) && intval(Facebook::getUser()->id) === intval($siteUser->id);
         $escapedMsg = URLHelpers::escapeAndReplaceUrls($a->msg);
         $comments[] = array("id" => intval($a->id), "profilePicUri" => !is_null($siteUser) ? $siteUser->getProfilePicUri(100, 100) : Config::get("comments.station_profile_picture_uri"), "postTime" => $a->created_at->timestamp, "name" => !is_null($siteUser) ? $siteUser->name : Config::get("comments.station_name"), "escapedMsg" => $escapedMsg, "permissionToDelete" => $permissionToDelete, "edited" => (bool) $a->edited);
     }
     $response = array("comments" => $comments, "more" => $more);
     return Response::json($response);
 }