pull/470/head
tidusjar 8 years ago
parent 4eff175424
commit d7997d5cc0

@ -43,6 +43,6 @@ namespace PlexRequests.Api.Interfaces
PlexEpisodeMetadata GetEpisodeMetaData(string authToken, Uri host, string ratingKey);
PlexSearch GetAllEpisodes(string authToken, Uri host, string section, int startPage, int returnCount);
PlexServer GetServer(string authToken);
PlexMetadata GetSeasons(string authToken, Uri plexFullHost, string ratingKey);
PlexSeasonMetadata GetSeasons(string authToken, Uri plexFullHost, string ratingKey);
}
}

@ -55,4 +55,29 @@ namespace PlexRequests.Api.Models.Plex
public string MediaTagVersion { get; set; }
}
[XmlRoot(ElementName = "MediaContainer")]
public class PlexSeasonMetadata
{
[XmlElement(ElementName = "Video")]
public Video Video { get; set; }
[XmlElement(ElementName = "Directory")]
public List<Directory1> Directory { get; set; }
[XmlAttribute(AttributeName = "size")]
public string Size { get; set; }
[XmlAttribute(AttributeName = "allowSync")]
public string AllowSync { get; set; }
[XmlAttribute(AttributeName = "identifier")]
public string Identifier { get; set; }
[XmlAttribute(AttributeName = "librarySectionID")]
public string LibrarySectionID { get; set; }
[XmlAttribute(AttributeName = "librarySectionTitle")]
public string LibrarySectionTitle { get; set; }
[XmlAttribute(AttributeName = "librarySectionUUID")]
public string LibrarySectionUUID { get; set; }
[XmlAttribute(AttributeName = "mediaTagPrefix")]
public string MediaTagPrefix { get; set; }
[XmlAttribute(AttributeName = "mediaTagVersion")]
public string MediaTagVersion { get; set; }
}
}

@ -244,6 +244,10 @@ namespace PlexRequests.Api.Models.Plex
[XmlRoot(ElementName = "Directory")]
public class Directory1
{
public Directory1()
{
Seasons = new List<Directory1>();
}
public string ProviderId { get; set; }
[XmlAttribute(AttributeName = "guid")]
public string Guid { get; set; }

@ -302,7 +302,7 @@ namespace PlexRequests.Api
}
public PlexMetadata GetSeasons(string authToken, Uri plexFullHost, string ratingKey)
public PlexSeasonMetadata GetSeasons(string authToken, Uri plexFullHost, string ratingKey)
{
var request = new RestRequest
{
@ -315,7 +315,7 @@ namespace PlexRequests.Api
try
{
var lib = RetryHandler.Execute(() => Api.ExecuteXml<PlexMetadata>(request, plexFullHost),
var lib = RetryHandler.Execute(() => Api.ExecuteXml<PlexSeasonMetadata>(request, plexFullHost),
(exception, timespan) => Log.Error(exception, "Exception when calling GetMetadata for Plex, Retrying {0}", timespan), new[] {
TimeSpan.FromSeconds (5),
TimeSpan.FromSeconds(10),
@ -327,7 +327,7 @@ namespace PlexRequests.Api
catch (Exception e)
{
Log.Error(e, "There has been a API Exception when attempting to get the Plex GetMetadata");
return new PlexMetadata();
return new PlexSeasonMetadata();
}
}

@ -28,6 +28,10 @@ namespace PlexRequests.Core.SettingModels
{
public sealed class PlexSettings : ExternalSettings
{
public PlexSettings()
{
AdvancedSearch = true;
}
public bool AdvancedSearch { get; set; }
public bool EnableTvEpisodeSearching { get; set; }

@ -30,10 +30,10 @@ namespace PlexRequests.Core.SettingModels
{
public ScheduledJobsSettings()
{
PlexAvailabilityChecker = 10;
SickRageCacher = 10;
SonarrCacher = 10;
CouchPotatoCacher = 10;
PlexAvailabilityChecker = 60;
SickRageCacher = 60;
SonarrCacher = 60;
CouchPotatoCacher = 60;
StoreBackup = 24;
StoreCleanup = 24;
UserRequestLimitResetter = 12;

@ -181,7 +181,7 @@ namespace PlexRequests.Services.Jobs
{
if (advanced)
{
if (!string.IsNullOrEmpty(movie.ProviderId) &&
if (!string.IsNullOrEmpty(movie.ProviderId) &&
movie.ProviderId.Equals(providerId, StringComparison.InvariantCultureIgnoreCase))
{
return true;
@ -209,7 +209,8 @@ namespace PlexRequests.Services.Jobs
).ToArray();
foreach (var lib in tvLibs)
{
{
shows.AddRange(lib.Directory.Select(x => new PlexTvShow // shows are in the directory list
{
Title = x.Title,
@ -229,14 +230,15 @@ namespace PlexRequests.Services.Jobs
{
if (advanced)
{
if (seasons != null)
if (seasons != null && show.ProviderId == providerId)
{
if (seasons.Any(season => show.Seasons.Contains(season)))
{
return true;
}
return false;
}
if (!string.IsNullOrEmpty(show.ProviderId) &&
if (!string.IsNullOrEmpty(show.ProviderId) &&
show.ProviderId.Equals(providerId, StringComparison.InvariantCultureIgnoreCase))
{
return true;
@ -257,14 +259,14 @@ namespace PlexRequests.Services.Jobs
connection =>
{
connection.Open();
var result = connection.Query<PlexEpisodes>("select * from PlexEpisodes where ProviderId = @ProviderId", new { ProviderId = theTvDbId});
var result = connection.Query<PlexEpisodes>("select * from PlexEpisodes where ProviderId = @ProviderId", new { ProviderId = theTvDbId });
return result;
}).ToList();
if (!ep.Any())
{
Log.Info("Episode cache info is not available. tvdbid: {0}, season: {1}, episode: {2}",theTvDbId, season, episode);
Log.Info("Episode cache info is not available. tvdbid: {0}, season: {1}, episode: {2}", theTvDbId, season, episode);
return false;
}
foreach (var result in ep)
@ -298,13 +300,13 @@ namespace PlexRequests.Services.Jobs
/// <returns></returns>
public async Task<IEnumerable<PlexEpisodes>> GetEpisodes(int theTvDbId)
{
var ep = await EpisodeRepo.CustomAsync(async connection =>
{
connection.Open();
var result = await connection.QueryAsync<PlexEpisodes>("select * from PlexEpisodes where ProviderId = @ProviderId", new { ProviderId = theTvDbId });
var ep = await EpisodeRepo.CustomAsync(async connection =>
{
connection.Open();
var result = await connection.QueryAsync<PlexEpisodes>("select * from PlexEpisodes where ProviderId = @ProviderId", new { ProviderId = theTvDbId });
return result;
});
return result;
});
var plexEpisodeses = ep as PlexEpisodes[] ?? ep.ToArray();
if (!plexEpisodeses.Any())
@ -373,8 +375,23 @@ namespace PlexRequests.Services.Jobs
var currentItem = results[i].Directory[j];
var metaData = PlexApi.GetMetadata(plexSettings.PlexAuthToken, plexSettings.FullUri,
currentItem.RatingKey);
var seasons = PlexApi.GetSeasons(plexSettings.PlexAuthToken, plexSettings.FullUri, currentItem.RatingKey);
results[i].Directory[j] = seasons.Directory;
// Get the seasons for each show
if (currentItem.Type.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase))
{
var seasons = PlexApi.GetSeasons(plexSettings.PlexAuthToken, plexSettings.FullUri,
currentItem.RatingKey);
// We do not want "all episodes" this as a season
var filtered =
seasons.Directory.Where(
x =>
!x.Title.Equals("All episodes",
StringComparison.CurrentCultureIgnoreCase));
results[i].Directory[j].Seasons.AddRange(filtered);
}
var providerId = PlexHelper.GetProviderIdFromPlexGuid(metaData.Directory.Guid);
results[i].Directory[j].ProviderId = providerId;
}

@ -584,7 +584,7 @@ $(function () {
var $form = $('#form' + tvId);
var model = [];
var $checkedEpisodes = $('.selectedEpisodes:checkbox:checked');
var $checkedEpisodes = $('.selectedEpisodes:checkbox:checked:not(:disabled)');
$checkedEpisodes.each(function (index, element) {
var $element = $('#' + element.id);
var tempObj = {};
@ -610,7 +610,7 @@ $(function () {
success: function (response) {
finishLoading("episodesRequest", "primary", origHtml);
if (response.result === true) {
generateNotify(response.message);
generateNotify(response.message, "success");
} else {
generateNotify(response.message, "warning");
}

@ -26,6 +26,9 @@ function utcToLocal(date) {
function generateNotify(message, type) {
// type = danger, warning, info, successs
if (!type) {
type = "success";
}
$.notify({
// options
message: message

@ -566,34 +566,6 @@ namespace PlexRequests.UI.Modules
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Our TV Provider (TVMaze) doesn't have a TheTVDBId for this item. Please report this to TVMaze. We cannot add the series sorry." });
}
// check if the show/episodes have already been requested
var existingRequest = await RequestService.CheckRequestAsync(showId);
var difference = new List<EpisodesModel>();
if (existingRequest != null)
{
if (episodeRequest)
{
difference = GetListDifferences(existingRequest.Episodes, episodeModel.Episodes).ToList();
if (difference.Any())
{
existingRequest.Episodes = episodeModel.Episodes
.Select(r =>
new EpisodesModel
{
SeasonNumber = r.SeasonNumber,
EpisodeNumber = r.EpisodeNumber
}).ToList();
return await AddUserToRequest(existingRequest, settings, fullShowName);
}
// We have an episode that has not yet been requested, let's continue
}
else
{
return await AddUserToRequest(existingRequest, settings, fullShowName);
}
}
var model = new RequestedModel
{
ProviderId = showInfo.externals?.thetvdb ?? 0,
@ -652,6 +624,45 @@ namespace PlexRequests.UI.Modules
model.SeasonList = seasonsList.ToArray();
// check if the show/episodes have already been requested
var existingRequest = await RequestService.CheckRequestAsync(showId);
var difference = new List<EpisodesModel>();
if (existingRequest != null)
{
if (episodeRequest)
{
// Make sure we are not somehow adding dupes
difference = GetListDifferences(existingRequest.Episodes, episodeModel.Episodes).ToList();
if (difference.Any())
{
// Convert the request into the correct shape
var newEpisodes = episodeModel.Episodes?.Select(x => new EpisodesModel
{
SeasonNumber = x.SeasonNumber,
EpisodeNumber = x.EpisodeNumber
});
// Add it to the existing requests
existingRequest.Episodes.AddRange(newEpisodes ?? Enumerable.Empty<EpisodesModel>());
// It's technically a new request now, so set the status to not approved.
existingRequest.Approved = false;
return await AddUserToRequest(existingRequest, settings, fullShowName);
}
// We have an episode that has not yet been requested, let's continue
}
else if (model.SeasonList.Except(existingRequest.SeasonList).Any())
{
// This is a season being requested that we do not yet have
// Let's just continue
}
else
{
return await AddUserToRequest(existingRequest, settings, fullShowName);
}
}
try
{
var shows = Checker.GetPlexTvShows();
@ -673,11 +684,7 @@ namespace PlexRequests.UI.Modules
}
}
var episodes = await GetEpisodes(showId);
var availableEpisodes = episodes.Where(x => x.Requested).ToList();
var availble = availableEpisodes.Select(a => new EpisodesModel { EpisodeNumber = a.EpisodeNumber, SeasonNumber = a.SeasonNumber }).ToList();
var diff = model.Episodes.Except(availble);
var diff = await GetEpisodeRequestDifference(showId, model);
model.Episodes = diff.ToList();
}
else
@ -704,6 +711,11 @@ namespace PlexRequests.UI.Modules
var result = await sender.SendToSonarr(s, model);
if (!string.IsNullOrEmpty(result?.title))
{
if (existingRequest != null)
{
return await UpdateRequest(model, settings,
$"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
}
return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
}
Log.Debug("Error with sending to sonarr.");
@ -735,21 +747,14 @@ namespace PlexRequests.UI.Modules
private async Task<Response> AddUserToRequest(RequestedModel existingRequest, PlexRequestSettings settings, string fullShowName)
{
// check if the current user is already marked as a requester for this show, if not, add them
if (!existingRequest.UserHasRequested(Username) || existingRequest.Episodes.Any())
if (!existingRequest.UserHasRequested(Username))
{
existingRequest.RequestedUsers.Add(Username);
await RequestService.UpdateRequestAsync(existingRequest);
}
return
Response.AsJson(
new JsonResponseModel
{
Result = true,
Message =
settings.UsersCanViewOnlyOwnRequests
? $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"
: $"{fullShowName} {Resources.UI.Search_AlreadyRequested}"
});
return await UpdateRequest(existingRequest, settings, settings.UsersCanViewOnlyOwnRequests
? $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"
: $"{fullShowName} {Resources.UI.Search_AlreadyRequested}");
}
private bool ShouldSendNotification(RequestType type, PlexRequestSettings prSettings)
@ -1103,6 +1108,44 @@ namespace PlexRequests.UI.Modules
return Response.AsJson(new JsonResponseModel { Result = true, Message = message });
}
private async Task<Response> UpdateRequest(RequestedModel model, PlexRequestSettings settings, string message)
{
await RequestService.UpdateRequestAsync(model);
if (ShouldSendNotification(model.Type, settings))
{
var notificationModel = new NotificationModel
{
Title = model.Title,
User = Username,
DateTime = DateTime.Now,
NotificationType = NotificationType.NewRequest,
RequestType = model.Type
};
await NotificationService.Publish(notificationModel);
}
var limit = await RequestLimitRepo.GetAllAsync();
var usersLimit = limit.FirstOrDefault(x => x.Username == Username && x.RequestType == model.Type);
if (usersLimit == null)
{
await RequestLimitRepo.InsertAsync(new RequestLimit
{
Username = Username,
RequestType = model.Type,
FirstRequestDate = DateTime.UtcNow,
RequestCount = 1
});
}
else
{
usersLimit.RequestCount++;
await RequestLimitRepo.UpdateAsync(usersLimit);
}
return Response.AsJson(new JsonResponseModel { Result = true, Message = message });
}
private IEnumerable<Store.EpisodesModel> GetListDifferences(IEnumerable<EpisodesModel> existing, IEnumerable<Models.EpisodesModel> request)
{
var newRequest = request
@ -1115,5 +1158,15 @@ namespace PlexRequests.UI.Modules
return newRequest.Except(existing);
}
private async Task<IEnumerable<EpisodesModel>> GetEpisodeRequestDifference(int showId, RequestedModel model)
{
var episodes = await GetEpisodes(showId);
var availableEpisodes = episodes.Where(x => x.Requested).ToList();
var available = availableEpisodes.Select(a => new EpisodesModel { EpisodeNumber = a.EpisodeNumber, SeasonNumber = a.SeasonNumber }).ToList();
var diff = model.Episodes.Except(available);
return diff;
}
}
}

Loading…
Cancel
Save