Beispiel #1
0
        private void GenerateTvHtml(List <RecentlyAddedChild> tv, PlexSettings plexSettings, StringBuilder sb)
        {
            var orderedTv = tv.OrderByDescending(x => x?.addedAt.UnixTimeStampToDateTime()).ToList();

            // TV
            sb.Append("<h1>New Episodes:</h1><br/><br/>");
            sb.Append(
                "<table border=\"0\" cellpadding=\"0\"  align=\"center\" cellspacing=\"0\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;\" width=\"100%\">");
            foreach (var t in orderedTv)
            {
                var plexGUID = string.Empty;
                try
                {
                    var parentMetaData = Api.GetMetadata(plexSettings.PlexAuthToken, plexSettings.FullUri,
                                                         t.parentRatingKey.ToString());

                    plexGUID = parentMetaData.Directory.Guid;

                    var info = TvApi.ShowLookupByTheTvDbId(int.Parse(PlexHelper.GetProviderIdFromPlexGuid(plexGUID)));

                    var banner = info.image?.original;
                    if (!string.IsNullOrEmpty(banner))
                    {
                        banner = banner.Replace("http", "https"); // Always use the Https banners
                    }
                    AddImageInsideTable(sb, banner);

                    sb.Append("<tr>");
                    sb.Append(
                        "<td align=\"center\" style=\"font-family: sans-serif; font-size: 14px; vertical-align: top;\" valign=\"top\">");

                    var title = $"{t.grandparentTitle} - {t.title}  {t.originallyAvailableAt?.Substring(0, 4)}";

                    Href(sb, $"https://www.imdb.com/title/{info.externals.imdb}/");
                    Header(sb, 3, title);
                    EndTag(sb, "a");

                    AddParagraph(sb, $"Season: {t.parentIndex}, Episode: {t.index}");
                    if (info.genres.Any())
                    {
                        AddParagraph(sb, $"Genre: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
                    }

                    AddParagraph(sb, string.IsNullOrEmpty(t.summary) ? info.summary : t.summary);
                }
                catch (Exception e)
                {
                    Log.Error(e);
                    Log.Error(
                        "Exception when trying to process a TV Show, either in getting the metadata from Plex OR getting the information from TVMaze, Plex GUID = {0}",
                        plexGUID);
                }
                finally
                {
                    EndLoopHtml(sb);
                }
            }
            sb.Append("</table><br/><br/>");
        }
Beispiel #2
0
        public async Task <SearchTvShowViewModel> GetShowInformation(string tvdbid, CancellationToken token)
        {
            var show = await Cache.GetOrAdd(nameof(GetShowInformation) + tvdbid,
                                            async() => await TvMazeApi.ShowLookupByTheTvDbId(int.Parse(tvdbid)), DateTime.Now.AddHours(12));

            if (show == null)
            {
                // We don't have enough information
                return(null);
            }

            var episodes = await Cache.GetOrAdd("TvMazeEpisodeLookup" + show.id,
                                                async() => await TvMazeApi.EpisodeLookup(show.id), DateTime.Now.AddHours(12));

            if (episodes == null || !episodes.Any())
            {
                // We don't have enough information
                return(null);
            }

            var mapped = Mapper.Map <SearchTvShowViewModel>(show);

            foreach (var e in episodes)
            {
                var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
                if (season == null)
                {
                    var newSeason = new SeasonRequests
                    {
                        SeasonNumber = e.season,
                        Episodes     = new List <EpisodeRequests>()
                    };
                    newSeason.Episodes.Add(new EpisodeRequests
                    {
                        Url           = e.url.ToHttpsUrl(),
                        Title         = e.name,
                        AirDate       = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
                        EpisodeNumber = e.number,
                    });
                    mapped.SeasonRequests.Add(newSeason);
                }
                else
                {
                    // We already have the season, so just add the episode
                    season.Episodes.Add(new EpisodeRequests
                    {
                        Url           = e.url.ToHttpsUrl(),
                        Title         = e.name,
                        AirDate       = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
                        EpisodeNumber = e.number,
                    });
                }
            }

            return(await ProcessResult(mapped, false));
        }
        private Response GetSeasons()
        {
            var tv       = new TvMazeApi();
            var seriesId = (int)Request.Query.tvId;
            var show     = tv.ShowLookupByTheTvDbId(seriesId);
            var seasons  = tv.GetSeasons(show.id);
            var model    = seasons.Select(x => x.number);

            return(Response.AsJson(model));
        }
Beispiel #4
0
        public async Task <SearchTvShowViewModel> GetShowInformation(int tvdbid)
        {
            var show = await TvMazeApi.ShowLookupByTheTvDbId(tvdbid);

            if (show == null)
            {
                // We don't have enough information
                return(null);
            }
            var episodes = await TvMazeApi.EpisodeLookup(show.id);

            if (episodes == null || !episodes.Any())
            {
                // We don't have enough information
                return(null);
            }

            var mapped = Mapper.Map <SearchTvShowViewModel>(show);

            foreach (var e in episodes)
            {
                var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
                if (season == null)
                {
                    var newSeason = new SeasonRequests
                    {
                        SeasonNumber = e.season,
                        Episodes     = new List <EpisodeRequests>()
                    };
                    newSeason.Episodes.Add(new EpisodeRequests
                    {
                        Url           = e.url,
                        Title         = e.name,
                        AirDate       = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
                        EpisodeNumber = e.number,
                    });
                    mapped.SeasonRequests.Add(newSeason);
                }
                else
                {
                    // We already have the season, so just add the episode
                    season.Episodes.Add(new EpisodeRequests
                    {
                        Url           = e.url,
                        Title         = e.name,
                        AirDate       = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
                        EpisodeNumber = e.number,
                    });
                }
            }
            return(await ProcessResult(mapped));
        }
        /// <summary>
        /// Requests the tv show.
        /// </summary>
        /// <param name="showId">The show identifier.</param>
        /// <param name="seasons">The seasons.</param>
        /// <param name="notify">if set to <c>true</c> [notify].</param>
        /// <returns></returns>
        private Response RequestTvShow(int showId, string seasons)
        {
            var tvApi = new TvMazeApi();

            var      showInfo = tvApi.ShowLookupByTheTvDbId(showId);
            DateTime firstAir;

            DateTime.TryParse(showInfo.premiered, out firstAir);
            string fullShowName = $"{showInfo.name} ({firstAir.Year})";
            //#if !DEBUG

            var settings = PrService.GetSettings();

            // check if the show has already been requested
            Log.Info("Requesting tv show with id {0}", showId);
            var existingRequest = RequestService.CheckRequest(showId);

            if (existingRequest != null)
            {
                // check if the current user is already marked as a requester for this show, if not, add them
                if (!existingRequest.UserHasRequested(Username))
                {
                    existingRequest.RequestedUsers.Add(Username);
                    RequestService.UpdateRequest(existingRequest);
                }
                return(Response.AsJson(new JsonResponseModel {
                    Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{fullShowName} was successfully added!" : $"{fullShowName} has already been requested!"
                }));
            }

            try
            {
                var shows = Checker.GetPlexTvShows();
                if (Checker.IsTvShowAvailable(shows.ToArray(), showInfo.name, showInfo.premiered?.Substring(0, 4)))
                {
                    return(Response.AsJson(new JsonResponseModel {
                        Result = false, Message = $"{fullShowName} is already in Plex!"
                    }));
                }
            }
            catch (ApplicationSettingsException)
            {
                return(Response.AsJson(new JsonResponseModel {
                    Result = false, Message = $"We could not check if {fullShowName} is in Plex, are you sure it's correctly setup?"
                }));
            }
            //#endif


            var model = new RequestedModel
            {
                ProviderId     = showInfo.externals?.thetvdb ?? 0,
                Type           = RequestType.TvShow,
                Overview       = showInfo.summary.RemoveHtml(),
                PosterPath     = showInfo.image?.medium,
                Title          = showInfo.name,
                ReleaseDate    = firstAir,
                Status         = showInfo.status,
                RequestedDate  = DateTime.UtcNow,
                Approved       = false,
                RequestedUsers = new List <string> {
                    Username
                },
                Issues      = IssueState.None,
                ImdbId      = showInfo.externals?.imdb ?? string.Empty,
                SeasonCount = showInfo.seasonCount
            };

            var seasonsList = new List <int>();

            switch (seasons)
            {
            case "first":
                seasonsList.Add(1);
                model.SeasonsRequested = "First";
                break;

            case "latest":
                seasonsList.Add(model.SeasonCount);
                model.SeasonsRequested = "Latest";
                break;

            case "all":
                model.SeasonsRequested = "All";
                break;

            default:
                var split        = seasons.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var seasonsCount = new int[split.Length];
                for (var i = 0; i < split.Length; i++)
                {
                    int tryInt;
                    int.TryParse(split[i], out tryInt);
                    seasonsCount[i] = tryInt;
                }
                seasonsList.AddRange(seasonsCount);
                break;
            }

            model.SeasonList = seasonsList.ToArray();

            if (ShouldAutoApprove(RequestType.TvShow, settings))
            {
                var sonarrSettings = SonarrService.GetSettings();
                var sender         = new TvSender(SonarrApi, SickrageApi);
                if (sonarrSettings.Enabled)
                {
                    var result = sender.SendToSonarr(sonarrSettings, model);
                    if (result != null && !string.IsNullOrEmpty(result.title))
                    {
                        model.Approved = true;
                        Log.Debug("Adding tv to database requests (No approval required & Sonarr)");
                        RequestService.AddRequest(model);

                        if (ShouldSendNotification())
                        {
                            var notify1 = new NotificationModel
                            {
                                Title            = model.Title,
                                User             = Username,
                                DateTime         = DateTime.Now,
                                NotificationType = NotificationType.NewRequest
                            };
                            NotificationService.Publish(notify1);
                        }
                        return(Response.AsJson(new JsonResponseModel {
                            Result = true, Message = $"{fullShowName} was successfully added!"
                        }));
                    }


                    return(Response.AsJson(ValidationHelper.SendSonarrError(result?.ErrorMessages)));
                }

                var srSettings = SickRageService.GetSettings();
                if (srSettings.Enabled)
                {
                    var result = sender.SendToSickRage(srSettings, model);
                    if (result?.result == "success")
                    {
                        model.Approved = true;
                        Log.Debug("Adding tv to database requests (No approval required & SickRage)");
                        RequestService.AddRequest(model);
                        if (ShouldSendNotification())
                        {
                            var notify2 = new NotificationModel
                            {
                                Title            = model.Title,
                                User             = Username,
                                DateTime         = DateTime.Now,
                                NotificationType = NotificationType.NewRequest
                            };
                            NotificationService.Publish(notify2);
                        }

                        return(Response.AsJson(new JsonResponseModel {
                            Result = true, Message = $"{fullShowName} was successfully added!"
                        }));
                    }
                    return(Response.AsJson(new JsonResponseModel {
                        Result = false, Message = result?.message != null ? "<b>Message From SickRage: </b>" + result.message : "Something went wrong adding the movie to SickRage! Please check your settings."
                    }));
                }

                return(Response.AsJson(new JsonResponseModel {
                    Result = false, Message = "The request of TV Shows is not correctly set up. Please contact your admin."
                }));
            }

            RequestService.AddRequest(model);

            var notificationModel = new NotificationModel {
                Title = model.Title, User = Username, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest
            };

            NotificationService.Publish(notificationModel);

            return(Response.AsJson(new JsonResponseModel {
                Result = true, Message = $"{fullShowName} was successfully added!"
            }));
        }
Beispiel #6
0
        private async Task <Response> ReportNonRequestIssue(int providerId, string type, IssueState issue, string comment)
        {
            var currentIssues = await IssuesService.GetAllAsync();

            var notifyModel = new NotificationModel
            {
                User             = Username,
                NotificationType = NotificationType.Issue,
                DateTime         = DateTime.Now,
                Body             = issue == IssueState.Other ? comment : issue.ToString().ToCamelCaseWords()
            };
            var model = new IssueModel
            {
                Issue        = issue,
                UserReported = Username,
                UserNote     = !string.IsNullOrEmpty(comment)
                ? $"{Username} - {comment}"
                : string.Empty,
            };

            var existing = currentIssues.FirstOrDefault(x => x.ProviderId == providerId && !x.Deleted && x.IssueStatus == IssueStatus.PendingIssue);

            if (existing != null)
            {
                existing.Issues.Add(model);
                await IssuesService.UpdateIssueAsync(existing);

                return(Response.AsJson(new JsonResponseModel {
                    Result = true
                }));
            }

            if (type == "movie")
            {
                var movieApi = new TheMovieDbApi();

                var result = await movieApi.GetMovieInformation(providerId);

                if (result != null)
                {
                    notifyModel.Title = result.Title;
                    // New issue
                    var issues = new IssuesModel
                    {
                        Title       = result.Title,
                        PosterUrl   = "https://image.tmdb.org/t/p/w150/" + result.PosterPath,
                        ProviderId  = providerId,
                        Type        = RequestType.Movie,
                        IssueStatus = IssueStatus.PendingIssue
                    };
                    issues.Issues.Add(model);

                    var issueId = await IssuesService.AddIssueAsync(issues);

                    await NotificationService.Publish(notifyModel);

                    return(Response.AsJson(new JsonResponseModel {
                        Result = true
                    }));
                }
            }

            if (type == "tv")
            {
                var tv     = new TvMazeApi();
                var result = tv.ShowLookupByTheTvDbId(providerId);
                if (result != null)
                {
                    var banner = result.image?.medium;
                    if (!string.IsNullOrEmpty(banner))
                    {
                        banner = banner.Replace("http", "https");
                    }

                    notifyModel.Title = result.name;
                    // New issue
                    var issues = new IssuesModel
                    {
                        Title       = result.name,
                        PosterUrl   = banner,
                        ProviderId  = providerId,
                        Type        = RequestType.TvShow,
                        IssueStatus = IssueStatus.PendingIssue
                    };
                    issues.Issues.Add(model);

                    var issueId = await IssuesService.AddIssueAsync(issues);

                    await NotificationService.Publish(notifyModel);

                    return(Response.AsJson(new JsonResponseModel {
                        Result = true
                    }));
                }
            }



            return(Response.AsJson(new JsonResponseModel {
                Result = false, Message = "Album Reports are not supported yet!"
            }));
        }
Beispiel #7
0
        private void MigrateDbFrom1300() // TODO: Remove in v1.7
        {
            var result = new List <long>();

            RequestedModel[] requestedModels;
            var repo = new GenericRepository <RequestedModel>(Db, new MemoryCacheProvider());

            try
            {
                var records = repo.GetAll();
                requestedModels = records as RequestedModel[] ?? records.ToArray();
            }
            catch (SqliteException)
            {
                // There is no requested table so they do not have an old version of the DB
                return;
            }

            if (!requestedModels.Any())
            {
                return;
            }

            var jsonRepo = new JsonRequestService(new RequestJsonRepository(Db, new MemoryCacheProvider()));

            var api = new TvMazeApi();

            foreach (var r in requestedModels.Where(x => x.Type == RequestType.TvShow))
            {
                var show = api.ShowLookupByTheTvDbId(r.ProviderId);

                var model = new RequestedModel
                {
                    Title          = show.name,
                    PosterPath     = show.image?.medium,
                    Type           = RequestType.TvShow,
                    ProviderId     = show.externals.thetvdb ?? 0,
                    ReleaseDate    = r.ReleaseDate,
                    AdminNote      = r.AdminNote,
                    Approved       = r.Approved,
                    Available      = r.Available,
                    ImdbId         = show.externals.imdb,
                    Issues         = r.Issues,
                    OtherMessage   = r.OtherMessage,
                    Overview       = show.summary.RemoveHtml(),
                    RequestedUsers = r.AllUsers, // should pull in the RequestedBy property and merge with RequestedUsers
                    RequestedDate  = r.ReleaseDate,
                    Status         = show.status
                };
                var id = jsonRepo.AddRequest(model);
                result.Add(id);
            }

            foreach (var source in requestedModels.Where(x => x.Type == RequestType.Movie))
            {
                var id = jsonRepo.AddRequest(source);
                result.Add(id);
            }


            if (result.Any(x => x == -1))
            {
                throw new SqliteException("Could not migrate the DB!");
            }


            if (result.Count != requestedModels.Length)
            {
                throw new SqliteException("Could not migrate the DB! count is different");
            }


            // Now delete the old requests
            foreach (var oldRequest in requestedModels)
            {
                repo.Delete(oldRequest);
            }
        }