mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-11 15:56:05 -07:00
merge
This commit is contained in:
commit
e77d54c6d1
51 changed files with 2766 additions and 307 deletions
48
.github/ISSUE_TEMPLATE.md
vendored
48
.github/ISSUE_TEMPLATE.md
vendored
|
@ -1,48 +0,0 @@
|
||||||
<!---
|
|
||||||
|
|
||||||
!! Please use the Support / bug report template, otherwise we will close the Github issue !!
|
|
||||||
|
|
||||||
Version 2.X is not supported anymore. Please don't open a issue for the 2.x version.
|
|
||||||
See https://github.com/tidusjar/Ombi/issues/1455 for more information.
|
|
||||||
|
|
||||||
(Pleas submit a feature request over here: http://feathub.com/tidusjar/Ombi)
|
|
||||||
|
|
||||||
|
|
||||||
--->
|
|
||||||
|
|
||||||
#### Ombi build Version:
|
|
||||||
|
|
||||||
V 3.0.XX
|
|
||||||
|
|
||||||
#### Update Branch:
|
|
||||||
|
|
||||||
Open Beta
|
|
||||||
|
|
||||||
#### Media Sever:
|
|
||||||
|
|
||||||
Plex/Emby
|
|
||||||
|
|
||||||
#### Media Server Version:
|
|
||||||
|
|
||||||
<!-- If appropriate --->
|
|
||||||
|
|
||||||
#### Operating System:
|
|
||||||
|
|
||||||
(Place text here)
|
|
||||||
|
|
||||||
|
|
||||||
#### Ombi Applicable Logs (from `/logs/` directory or the Admin page):
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
(Logs go here. Don't remove the ' tags for showing your logs correctly. Please make sure you remove any personal information from the logs)
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Problem Description:
|
|
||||||
|
|
||||||
(Place text here)
|
|
||||||
|
|
||||||
#### Reproduction Steps:
|
|
||||||
|
|
||||||
Please include any steps to reproduce the issue, this the request that is causing the problem etc.
|
|
37
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
37
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Logs (Logs directory where Ombi is located)**
|
||||||
|
If applicable, a snippet of the logs that seems relevant to the bug if present.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
|
||||||
|
**Ombi Version (please complete the following information):**
|
||||||
|
- Version [e.g. 3.0.1158]
|
||||||
|
- Media Server [e.g. Plex]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
88
CHANGELOG.md
88
CHANGELOG.md
|
@ -1,13 +1,8 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## (unreleased)
|
|
||||||
|
|
||||||
### **New Features**
|
## v3.0.4119 (2019-1-09)
|
||||||
|
|
||||||
- Added new classes to the posters #2732. [TidusJar]
|
|
||||||
|
|
||||||
|
|
||||||
## v3.0.4119 (2019-01-09)
|
|
||||||
|
|
||||||
### **New Features**
|
### **New Features**
|
||||||
|
|
||||||
|
@ -29,33 +24,27 @@
|
||||||
|
|
||||||
- Added the ability to specify a year when searching for movies. [tidusjar]
|
- Added the ability to specify a year when searching for movies. [tidusjar]
|
||||||
|
|
||||||
- Update NewsletterTemplate.html. [d1slact0r]
|
- Made the newsletter use the default lanuage code set in the Ombi settings for movie information. [TidusJar]
|
||||||
|
|
||||||
- Update NewsletterTemplate.html. [d1slact0r]
|
- Added a global language flag that now applies to the search by default. [tidusjar]
|
||||||
|
|
||||||
- Update NewsletterTemplate.html. [d1slact0r]
|
- Updated the frontend packages (Using Angular 7 now) [TidusJar]
|
||||||
|
|
||||||
- Update HtmlTemplateGenerator.cs. [d1slact0r]
|
- Added capture of anonymous analytical data. [tidusjar]
|
||||||
|
|
||||||
- Update NewsletterTemplate.html. [d1slact0r]
|
- Added {AvailableDate} as a Notification Variable, this is the date the request was marked as available. See here: https://github.com/tidusjar/Ombi/wiki/Notification-Template-Variables. [tidusjar]
|
||||||
|
|
||||||
- Update HtmlTemplateGenerator.cs. [d1slact0r]
|
- Updated the Newsletter template! Better mail client support [d1slact0r]
|
||||||
|
|
||||||
- Update NewsletterTemplate.html. [d1slact0r]
|
- Updated boostrap #2694. [TidusJar]
|
||||||
|
|
||||||
- Update NewsletterTemplate.html. [d1slact0r]
|
|
||||||
|
|
||||||
- Update NewsletterTemplate.html. [d1slact0r]
|
|
||||||
|
|
||||||
- Update HtmlTemplateGenerator.cs. [d1slact0r]
|
|
||||||
|
|
||||||
- Updated boostrap #2694. [Jamie]
|
|
||||||
|
|
||||||
- Added the ability to deny a request with a reason. [TidusJar]
|
- Added the ability to deny a request with a reason. [TidusJar]
|
||||||
|
- Updated to .net core 2.2 and included a linux-arm64 build. [aptalca]
|
||||||
|
|
||||||
- Update EmbyEpisodeSync.cs. [Jamie]
|
- Make the newsletter BCC the users rather than creating a million newsletters (Hopefully will stop SMTP providers from marking as spam). This does mean that the custom user customization in the newsletter will no longer work. [TidusJar]
|
||||||
|
|
||||||
- Updated to .net core 2.2 and included a linux-arm64 build. [TidusJar]
|
|
||||||
|
- New translations [TidusJar]
|
||||||
|
|
||||||
### **Fixes**
|
### **Fixes**
|
||||||
|
|
||||||
|
@ -77,62 +66,12 @@
|
||||||
|
|
||||||
- Fixed #2716. [tidusjar]
|
- Fixed #2716. [tidusjar]
|
||||||
|
|
||||||
- Make the newsletter BCC the users rather than creating a million newsletters (Hopefully will stop SMTP providers from marking as spam). This does mean that the custom user customization in the newsletter will no longer work. [TidusJar]
|
|
||||||
|
|
||||||
- If we don't know the Plex agent, then see if it's a ImdbId, if it's not check the string for any episode and season hints #2695. [tidusjar]
|
- If we don't know the Plex agent, then see if it's a ImdbId, if it's not check the string for any episode and season hints #2695. [tidusjar]
|
||||||
|
|
||||||
- New translations en.json (Swedish) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Spanish) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Portuguese, Brazilian) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Polish) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Norwegian) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Italian) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (German) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (French) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Dutch) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Danish) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Dutch) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Dutch) [Jamie]
|
|
||||||
|
|
||||||
- New translations en.json (Dutch) [Jamie]
|
|
||||||
|
|
||||||
- Made the search results the language specified in the search refinement. [tidusjar]
|
|
||||||
|
|
||||||
- Fixed #2704. [tidusjar]
|
- Fixed #2704. [tidusjar]
|
||||||
|
|
||||||
- Now it is fixed :) [d1slact0r]
|
|
||||||
|
|
||||||
- Android please be nice now. [d1slact0r]
|
|
||||||
|
|
||||||
- Fixed title bit better. [d1slact0r]
|
|
||||||
|
|
||||||
- Fixed titles. [d1slact0r]
|
|
||||||
|
|
||||||
- This should fix the build for sure (stupid quotes) [d1slact0r]
|
|
||||||
|
|
||||||
- Fixes build. [d1slact0r]
|
|
||||||
|
|
||||||
- Rewritten the whole newsletter template. [d1slact0r]
|
|
||||||
|
|
||||||
- Fixed #2697. [tidusjar]
|
- Fixed #2697. [tidusjar]
|
||||||
|
|
||||||
- Add linux-arm runtime identifier. [aptalca]
|
|
||||||
|
|
||||||
- Add back arm packages. [aptalca]
|
|
||||||
|
|
||||||
- Add arm32 package. [aptalca]
|
|
||||||
|
|
||||||
- Fixed #2691. [tidusjar]
|
- Fixed #2691. [tidusjar]
|
||||||
|
|
||||||
- Fixed linting. [TidusJar]
|
- Fixed linting. [TidusJar]
|
||||||
|
@ -141,13 +80,10 @@
|
||||||
|
|
||||||
- Fixed #2678. [TidusJar]
|
- Fixed #2678. [TidusJar]
|
||||||
|
|
||||||
- Deny reason for movie requests. [TidusJar]
|
|
||||||
|
|
||||||
- Set the landing and login pages background refresh to 15 seconds rather than 10 and 7. [TidusJar]
|
- Set the landing and login pages background refresh to 15 seconds rather than 10 and 7. [TidusJar]
|
||||||
|
|
||||||
- Fixed a bug with us thinking future dated emby episodes are not available, Consoldated the emby and plex search rules (since they have the same logic) [TidusJar]
|
- Fixed a bug with us thinking future dated emby episodes are not available, Consoldated the emby and plex search rules (since they have the same logic) [TidusJar]
|
||||||
|
|
||||||
- Fixed build. [TidusJar]
|
|
||||||
|
|
||||||
|
|
||||||
## v3.0.4036 (2018-12-11)
|
## v3.0.4036 (2018-12-11)
|
||||||
|
|
|
@ -117,13 +117,12 @@ Please feel free to submit a pull request!
|
||||||
# Donation
|
# Donation
|
||||||
If you feel like donating you can donate with the below buttons!
|
If you feel like donating you can donate with the below buttons!
|
||||||
|
|
||||||
[](https://patreon.com/tidusjar/Ombi)
|
|
||||||
[](https://paypal.me/PlexRequestsNet)
|
[](https://patreon.com/tidusjar/Ombi)
|
||||||
|
[](https://paypal.me/PlexRequestsNet)
|
||||||
|
|
||||||
### A massive thanks to everyone for all their help!
|
### A massive thanks to everyone for all their help!
|
||||||
|
|
||||||
## Stats
|
|
||||||
[](https://waffle.io/tidusjar/PlexRequests.Net/metrics/throughput)
|
|
||||||
|
|
||||||
### Sponsors ###
|
### Sponsors ###
|
||||||
- [JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools
|
- [JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools
|
||||||
|
|
|
@ -385,6 +385,7 @@ namespace Ombi.Core.Engine
|
||||||
foreach (var ep in s.Episodes)
|
foreach (var ep in s.Episodes)
|
||||||
{
|
{
|
||||||
ep.Approved = true;
|
ep.Approved = true;
|
||||||
|
ep.Requested = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ namespace Ombi.Core.Engine
|
||||||
{
|
{
|
||||||
Url = e.url,
|
Url = e.url,
|
||||||
Title = e.name,
|
Title = e.name,
|
||||||
AirDate = DateTime.Parse(e.airstamp ?? DateTime.MinValue.ToString()),
|
AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
|
||||||
EpisodeNumber = e.number,
|
EpisodeNumber = e.number,
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -112,7 +112,7 @@ namespace Ombi.Core.Engine
|
||||||
{
|
{
|
||||||
Url = e.url,
|
Url = e.url,
|
||||||
Title = e.name,
|
Title = e.name,
|
||||||
AirDate = DateTime.Parse(e.airstamp ?? DateTime.MinValue.ToString()),
|
AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
|
||||||
EpisodeNumber = e.number,
|
EpisodeNumber = e.number,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Linq;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Ombi.Core.Models.Search;
|
using Ombi.Core.Models.Search;
|
||||||
|
@ -87,11 +88,11 @@ namespace Ombi.Core.Rule.Rules.Search
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.All(e => e.Available)))
|
if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.All(e => e.Available && e.AirDate > DateTime.MinValue)))
|
||||||
{
|
{
|
||||||
request.FullyAvailable = true;
|
request.FullyAvailable = true;
|
||||||
}
|
}
|
||||||
if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.Any(e => e.Available)))
|
if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.Any(e => e.Available && e.AirDate > DateTime.MinValue)))
|
||||||
{
|
{
|
||||||
request.PartlyAvailable = true;
|
request.PartlyAvailable = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ namespace Ombi.Core.Senders
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
var cpSettings = await CouchPotatoSettings.GetSettingsAsync();
|
var cpSettings = await CouchPotatoSettings.GetSettingsAsync();
|
||||||
//var watcherSettings = await WatcherSettings.GetSettingsAsync();
|
//var watcherSettings = await WatcherSettings.GetSettingsAsync();
|
||||||
var radarrSettings = await RadarrSettings.GetSettingsAsync();
|
var radarrSettings = await RadarrSettings.GetSettingsAsync();
|
||||||
|
@ -76,7 +75,7 @@ namespace Ombi.Core.Senders
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.LogError(e, "Error when seing movie to DVR app, added to the request queue");
|
Log.LogError(e, "Error when sending movie to DVR app, added to the request queue");
|
||||||
|
|
||||||
// Check if already in request quee
|
// Check if already in request quee
|
||||||
var existingQueue = await _requestQueuRepository.FirstOrDefaultAsync(x => x.RequestId == model.Id);
|
var existingQueue = await _requestQueuRepository.FirstOrDefaultAsync(x => x.RequestId == model.Id);
|
||||||
|
|
|
@ -16,6 +16,7 @@ using Ombi.Settings.Settings.Models.External;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Entities.Requests;
|
using Ombi.Store.Entities.Requests;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
|
using Remotion.Linq.Parsing.Structure.IntermediateModel;
|
||||||
|
|
||||||
namespace Ombi.Core.Senders
|
namespace Ombi.Core.Senders
|
||||||
{
|
{
|
||||||
|
@ -57,7 +58,7 @@ namespace Ombi.Core.Senders
|
||||||
var sonarr = await SonarrSettings.GetSettingsAsync();
|
var sonarr = await SonarrSettings.GetSettingsAsync();
|
||||||
if (sonarr.Enabled)
|
if (sonarr.Enabled)
|
||||||
{
|
{
|
||||||
var result = await SendToSonarr(model);
|
var result = await SendToSonarr(model, sonarr);
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
return new SenderResult
|
return new SenderResult
|
||||||
|
@ -109,7 +110,7 @@ namespace Ombi.Core.Senders
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.LogError(e, "Exception thrown when sending a movie to DVR app, added to the request queue");
|
Logger.LogError(e, "Exception thrown when sending a movie to DVR app, added to the request queue");
|
||||||
// Check if already in request quee
|
// Check if already in request queue
|
||||||
var existingQueue = await _requestQueueRepository.FirstOrDefaultAsync(x => x.RequestId == model.Id);
|
var existingQueue = await _requestQueueRepository.FirstOrDefaultAsync(x => x.RequestId == model.Id);
|
||||||
if (existingQueue != null)
|
if (existingQueue != null)
|
||||||
{
|
{
|
||||||
|
@ -134,7 +135,7 @@ namespace Ombi.Core.Senders
|
||||||
return new SenderResult
|
return new SenderResult
|
||||||
{
|
{
|
||||||
Success = false,
|
Success = false,
|
||||||
Message = "Something wen't wrong!"
|
Message = "Something went wrong!"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,13 +151,8 @@ namespace Ombi.Core.Senders
|
||||||
/// <param name="s"></param>
|
/// <param name="s"></param>
|
||||||
/// <param name="model"></param>
|
/// <param name="model"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<NewSeries> SendToSonarr(ChildRequests model)
|
public async Task<NewSeries> SendToSonarr(ChildRequests model, SonarrSettings s)
|
||||||
{
|
{
|
||||||
var s = await SonarrSettings.GetSettingsAsync();
|
|
||||||
if (!s.Enabled)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(s.ApiKey))
|
if (string.IsNullOrEmpty(s.ApiKey))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -319,10 +315,19 @@ namespace Ombi.Core.Senders
|
||||||
|
|
||||||
foreach (var season in model.SeasonRequests)
|
foreach (var season in model.SeasonRequests)
|
||||||
{
|
{
|
||||||
var sonarrSeason = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber);
|
var sonarrEpisodeList = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber).ToList();
|
||||||
var sonarrEpCount = sonarrSeason.Count();
|
var sonarrEpCount = sonarrEpisodeList.Count;
|
||||||
var ourRequestCount = season.Episodes.Count;
|
var ourRequestCount = season.Episodes.Count;
|
||||||
|
|
||||||
|
var ourEpisodes = season.Episodes.Select(x => x.EpisodeNumber).ToList();
|
||||||
|
var unairedEpisodes = sonarrEpisodeList.Where(x => x.airDateUtc > DateTime.UtcNow).Select(x => x.episodeNumber).ToList();
|
||||||
|
|
||||||
|
//// Check if we have requested all the latest episodes, if we have then monitor
|
||||||
|
//// NOTE, not sure if needed since ombi ui displays future episodes anyway...
|
||||||
|
//ourEpisodes.AddRange(unairedEpisodes);
|
||||||
|
//var distinctEpisodes = ourEpisodes.Distinct().ToList();
|
||||||
|
//var missingEpisodes = Enumerable.Range(distinctEpisodes.Min(), distinctEpisodes.Count).Except(distinctEpisodes);
|
||||||
|
|
||||||
var existingSeason =
|
var existingSeason =
|
||||||
result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber);
|
result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber);
|
||||||
if (existingSeason == null)
|
if (existingSeason == null)
|
||||||
|
@ -332,7 +337,7 @@ namespace Ombi.Core.Senders
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (sonarrEpCount == ourRequestCount)
|
if (sonarrEpCount == ourRequestCount /*|| !missingEpisodes.Any()*/)
|
||||||
{
|
{
|
||||||
// We have the same amount of requests as all of the episodes in the season.
|
// We have the same amount of requests as all of the episodes in the season.
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@ namespace Ombi.Notifications
|
||||||
MovieRepository = movie;
|
MovieRepository = movie;
|
||||||
TvRepository = tv;
|
TvRepository = tv;
|
||||||
CustomizationSettings = customization;
|
CustomizationSettings = customization;
|
||||||
Settings.ClearCache();
|
|
||||||
CustomizationSettings.ClearCache();
|
|
||||||
RequestSubscription = sub;
|
RequestSubscription = sub;
|
||||||
_log = log;
|
_log = log;
|
||||||
AlbumRepository = album;
|
AlbumRepository = album;
|
||||||
|
@ -55,14 +53,12 @@ namespace Ombi.Notifications
|
||||||
|
|
||||||
public async Task NotifyAsync(NotificationOptions model)
|
public async Task NotifyAsync(NotificationOptions model)
|
||||||
{
|
{
|
||||||
Settings.ClearCache();
|
|
||||||
var configuration = await GetConfiguration();
|
var configuration = await GetConfiguration();
|
||||||
await NotifyAsync(model, configuration);
|
await NotifyAsync(model, configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task NotifyAsync(NotificationOptions model, Settings.Settings.Models.Settings settings)
|
public async Task NotifyAsync(NotificationOptions model, Settings.Settings.Models.Settings settings)
|
||||||
{
|
{
|
||||||
Settings.ClearCache();
|
|
||||||
if (settings == null) await NotifyAsync(model);
|
if (settings == null) await NotifyAsync(model);
|
||||||
|
|
||||||
var notificationSettings = (T)settings;
|
var notificationSettings = (T)settings;
|
||||||
|
|
|
@ -5,6 +5,7 @@ using MailKit.Net.Smtp;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
using Ombi.Core.Settings;
|
using Ombi.Core.Settings;
|
||||||
|
using Ombi.Helpers;
|
||||||
using Ombi.Notifications.Models;
|
using Ombi.Notifications.Models;
|
||||||
using Ombi.Notifications.Templates;
|
using Ombi.Notifications.Templates;
|
||||||
using Ombi.Settings.Settings.Models;
|
using Ombi.Settings.Settings.Models;
|
||||||
|
@ -56,6 +57,11 @@ namespace Ombi.Notifications
|
||||||
|
|
||||||
using (var client = new SmtpClient())
|
using (var client = new SmtpClient())
|
||||||
{
|
{
|
||||||
|
if (customization.ApplicationUrl.HasValue())
|
||||||
|
{
|
||||||
|
client.LocalDomain = customization.ApplicationUrl;
|
||||||
|
}
|
||||||
|
|
||||||
if (settings.DisableCertificateChecking)
|
if (settings.DisableCertificateChecking)
|
||||||
{
|
{
|
||||||
// Disable validation of the certificate associated with the SMTP service
|
// Disable validation of the certificate associated with the SMTP service
|
||||||
|
|
|
@ -28,7 +28,6 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_episodeSync = epSync;
|
_episodeSync = epSync;
|
||||||
_metadata = metadata;
|
_metadata = metadata;
|
||||||
_settings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ILogger<EmbyContentSync> _logger;
|
private readonly ILogger<EmbyContentSync> _logger;
|
||||||
|
|
|
@ -49,7 +49,6 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
_settings = s;
|
_settings = s;
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_avaliabilityChecker = checker;
|
_avaliabilityChecker = checker;
|
||||||
_settings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ISettingsService<EmbySettings> _settings;
|
private readonly ISettingsService<EmbySettings> _settings;
|
||||||
|
|
|
@ -50,8 +50,6 @@ namespace Ombi.Schedule.Jobs.Emby
|
||||||
_log = log;
|
_log = log;
|
||||||
_embySettings = embySettings;
|
_embySettings = embySettings;
|
||||||
_userManagementSettings = ums;
|
_userManagementSettings = ums;
|
||||||
_userManagementSettings.ClearCache();
|
|
||||||
_embySettings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IEmbyApi _api;
|
private readonly IEmbyApi _api;
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Internal;
|
using Microsoft.EntityFrameworkCore.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Ombi.Api.Lidarr;
|
using Ombi.Api.Lidarr;
|
||||||
using Ombi.Api.Radarr;
|
|
||||||
using Ombi.Core.Settings;
|
using Ombi.Core.Settings;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
using Ombi.Settings.Settings.Models.External;
|
using Ombi.Settings.Settings.Models.External;
|
||||||
using Ombi.Store.Context;
|
using Ombi.Store.Context;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Serilog;
|
|
||||||
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
||||||
|
|
||||||
namespace Ombi.Schedule.Jobs.Lidarr
|
namespace Ombi.Schedule.Jobs.Lidarr
|
||||||
|
@ -29,7 +26,6 @@ namespace Ombi.Schedule.Jobs.Lidarr
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
_job = job;
|
_job = job;
|
||||||
_availability = availability;
|
_availability = availability;
|
||||||
_lidarrSettings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Internal;
|
using Microsoft.EntityFrameworkCore.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Ombi.Api.Lidarr;
|
using Ombi.Api.Lidarr;
|
||||||
using Ombi.Api.Radarr;
|
|
||||||
using Ombi.Core.Settings;
|
using Ombi.Core.Settings;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
using Ombi.Settings.Settings.Models.External;
|
using Ombi.Settings.Settings.Models.External;
|
||||||
using Ombi.Store.Context;
|
using Ombi.Store.Context;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Serilog;
|
|
||||||
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
||||||
|
|
||||||
namespace Ombi.Schedule.Jobs.Lidarr
|
namespace Ombi.Schedule.Jobs.Lidarr
|
||||||
|
@ -29,7 +26,6 @@ namespace Ombi.Schedule.Jobs.Lidarr
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
_job = background;
|
_job = background;
|
||||||
_albumSync = album;
|
_albumSync = album;
|
||||||
_lidarrSettings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
||||||
|
|
|
@ -28,9 +28,9 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var now = DateTime.Now.AddDays(-settings.DaysAfterResolvedToDelete).Date;
|
var deletionDate = DateTime.Now.AddDays(settings.DaysAfterResolvedToDelete).Date;
|
||||||
var resolved = _issuesRepository.GetAll().Where(x => x.Status == IssueStatus.Resolved);
|
var resolved = _issuesRepository.GetAll().Where(x => x.Status == IssueStatus.Resolved);
|
||||||
var toDelete = resolved.Where(x => x.ResovledDate.HasValue && x.ResovledDate.Value.Date <= now);
|
var toDelete = resolved.Where(x => x.ResovledDate.HasValue && x.ResovledDate.Value.Date >= deletionDate);
|
||||||
|
|
||||||
foreach (var d in toDelete)
|
foreach (var d in toDelete)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,28 +10,23 @@ using Ombi.Schedule.Jobs.Emby;
|
||||||
using Ombi.Schedule.Jobs.Plex.Interfaces;
|
using Ombi.Schedule.Jobs.Plex.Interfaces;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
|
|
||||||
namespace Ombi.Schedule.Jobs.Plex
|
namespace Ombi.Schedule.Jobs.Ombi
|
||||||
{
|
{
|
||||||
public class MediaDatabaseRefresh : IMediaDatabaseRefresh
|
public class MediaDatabaseRefresh : IMediaDatabaseRefresh
|
||||||
{
|
{
|
||||||
public MediaDatabaseRefresh(ISettingsService<PlexSettings> s, ILogger<MediaDatabaseRefresh> log, IPlexApi plexApi,
|
public MediaDatabaseRefresh(ISettingsService<PlexSettings> s, ILogger<MediaDatabaseRefresh> log,
|
||||||
IPlexContentRepository plexRepo, IPlexContentSync c, IEmbyContentRepository embyRepo, IEmbyContentSync embySync)
|
IPlexContentRepository plexRepo, IEmbyContentRepository embyRepo, IEmbyContentSync embySync)
|
||||||
{
|
{
|
||||||
_settings = s;
|
_settings = s;
|
||||||
_log = log;
|
_log = log;
|
||||||
_api = plexApi;
|
|
||||||
_plexRepo = plexRepo;
|
_plexRepo = plexRepo;
|
||||||
_plexContentSync = c;
|
|
||||||
_embyRepo = embyRepo;
|
_embyRepo = embyRepo;
|
||||||
_embyContentSync = embySync;
|
_embyContentSync = embySync;
|
||||||
_settings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ISettingsService<PlexSettings> _settings;
|
private readonly ISettingsService<PlexSettings> _settings;
|
||||||
private readonly ILogger _log;
|
private readonly ILogger _log;
|
||||||
private readonly IPlexApi _api;
|
|
||||||
private readonly IPlexContentRepository _plexRepo;
|
private readonly IPlexContentRepository _plexRepo;
|
||||||
private readonly IPlexContentSync _plexContentSync;
|
|
||||||
private readonly IEmbyContentRepository _embyRepo;
|
private readonly IEmbyContentRepository _embyRepo;
|
||||||
private readonly IEmbyContentSync _embyContentSync;
|
private readonly IEmbyContentSync _embyContentSync;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ using Ombi.Api.TheMovieDb;
|
||||||
using Ombi.Api.TheMovieDb.Models;
|
using Ombi.Api.TheMovieDb.Models;
|
||||||
using Ombi.Api.TvMaze;
|
using Ombi.Api.TvMaze;
|
||||||
using Ombi.Core.Settings;
|
using Ombi.Core.Settings;
|
||||||
|
using Ombi.Core.Settings.Models.External;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
using Ombi.Notifications;
|
using Ombi.Notifications;
|
||||||
using Ombi.Notifications.Models;
|
using Ombi.Notifications.Models;
|
||||||
|
@ -36,7 +37,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
ISettingsService<EmailNotificationSettings> emailSettings, INotificationTemplatesRepository templateRepo,
|
ISettingsService<EmailNotificationSettings> emailSettings, INotificationTemplatesRepository templateRepo,
|
||||||
UserManager<OmbiUser> um, ISettingsService<NewsletterSettings> newsletter, ILogger<NewsletterJob> log,
|
UserManager<OmbiUser> um, ISettingsService<NewsletterSettings> newsletter, ILogger<NewsletterJob> log,
|
||||||
ILidarrApi lidarrApi, IRepository<LidarrAlbumCache> albumCache, ISettingsService<LidarrSettings> lidarrSettings,
|
ILidarrApi lidarrApi, IRepository<LidarrAlbumCache> albumCache, ISettingsService<LidarrSettings> lidarrSettings,
|
||||||
ISettingsService<OmbiSettings> ombiSettings)
|
ISettingsService<OmbiSettings> ombiSettings, ISettingsService<PlexSettings> plexSettings, ISettingsService<EmbySettings> embySettings)
|
||||||
{
|
{
|
||||||
_plex = plex;
|
_plex = plex;
|
||||||
_emby = emby;
|
_emby = emby;
|
||||||
|
@ -49,16 +50,13 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
_emailSettings = emailSettings;
|
_emailSettings = emailSettings;
|
||||||
_newsletterSettings = newsletter;
|
_newsletterSettings = newsletter;
|
||||||
_userManager = um;
|
_userManager = um;
|
||||||
_emailSettings.ClearCache();
|
|
||||||
_customizationSettings.ClearCache();
|
|
||||||
_newsletterSettings.ClearCache();
|
|
||||||
_log = log;
|
_log = log;
|
||||||
_lidarrApi = lidarrApi;
|
_lidarrApi = lidarrApi;
|
||||||
_lidarrAlbumRepository = albumCache;
|
_lidarrAlbumRepository = albumCache;
|
||||||
_lidarrSettings = lidarrSettings;
|
_lidarrSettings = lidarrSettings;
|
||||||
_ombiSettings = ombiSettings;
|
_ombiSettings = ombiSettings;
|
||||||
_ombiSettings.ClearCache();
|
_plexSettings = plexSettings;
|
||||||
_lidarrSettings.ClearCache();
|
_embySettings = embySettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IPlexContentRepository _plex;
|
private readonly IPlexContentRepository _plex;
|
||||||
|
@ -77,6 +75,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
private readonly ILidarrApi _lidarrApi;
|
private readonly ILidarrApi _lidarrApi;
|
||||||
private readonly IRepository<LidarrAlbumCache> _lidarrAlbumRepository;
|
private readonly IRepository<LidarrAlbumCache> _lidarrAlbumRepository;
|
||||||
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
||||||
|
private readonly ISettingsService<PlexSettings> _plexSettings;
|
||||||
|
private readonly ISettingsService<EmbySettings> _embySettings;
|
||||||
|
|
||||||
public async Task Start(NewsletterSettings settings, bool test)
|
public async Task Start(NewsletterSettings settings, bool test)
|
||||||
{
|
{
|
||||||
|
@ -132,6 +132,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
|
|
||||||
_log.LogInformation("Plex Episodes to send: {0}", plexEpisodesToSend.Count());
|
_log.LogInformation("Plex Episodes to send: {0}", plexEpisodesToSend.Count());
|
||||||
_log.LogInformation("Emby Episodes to send: {0}", embyEpisodesToSend.Count());
|
_log.LogInformation("Emby Episodes to send: {0}", embyEpisodesToSend.Count());
|
||||||
|
var plexSettings = await _plexSettings.GetSettingsAsync();
|
||||||
|
var embySettings = await _embySettings.GetSettingsAsync();
|
||||||
var body = string.Empty;
|
var body = string.Empty;
|
||||||
if (test)
|
if (test)
|
||||||
{
|
{
|
||||||
|
@ -140,11 +142,11 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
var plext = _plex.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10).ToHashSet();
|
var plext = _plex.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10).ToHashSet();
|
||||||
var embyt = _emby.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.AddedAt).Take(10).ToHashSet();
|
var embyt = _emby.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.AddedAt).Take(10).ToHashSet();
|
||||||
var lidarr = lidarrContent.OrderByDescending(x => x.AddedAt).Take(10).ToHashSet();
|
var lidarr = lidarrContent.OrderByDescending(x => x.AddedAt).Take(10).ToHashSet();
|
||||||
body = await BuildHtml(plexm, embym, plext, embyt, lidarr, settings);
|
body = await BuildHtml(plexm, embym, plext, embyt, lidarr, settings, embySettings, plexSettings);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
body = await BuildHtml(plexContentMoviesToSend, embyContentMoviesToSend, plexEpisodesToSend, embyEpisodesToSend, lidarrContentAlbumsToSend, settings);
|
body = await BuildHtml(plexContentMoviesToSend, embyContentMoviesToSend, plexEpisodesToSend, embyEpisodesToSend, lidarrContentAlbumsToSend, settings, embySettings, plexSettings);
|
||||||
if (body.IsNullOrEmpty())
|
if (body.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -333,7 +335,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> BuildHtml(IQueryable<PlexServerContent> plexContentToSend, IQueryable<EmbyContent> embyContentToSend,
|
private async Task<string> BuildHtml(IQueryable<PlexServerContent> plexContentToSend, IQueryable<EmbyContent> embyContentToSend,
|
||||||
HashSet<PlexEpisode> plexEpisodes, HashSet<EmbyEpisode> embyEp, HashSet<LidarrAlbumCache> albums, NewsletterSettings settings)
|
HashSet<PlexEpisode> plexEpisodes, HashSet<EmbyEpisode> embyEp, HashSet<LidarrAlbumCache> albums, NewsletterSettings settings, EmbySettings embySettings,
|
||||||
|
PlexSettings plexSettings)
|
||||||
{
|
{
|
||||||
var ombiSettings = await _ombiSettings.GetSettingsAsync();
|
var ombiSettings = await _ombiSettings.GetSettingsAsync();
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
@ -349,8 +352,16 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
|
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||||
sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">");
|
sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">");
|
||||||
sb.Append("<tr>");
|
sb.Append("<tr>");
|
||||||
await ProcessPlexMovies(plexMovies, sb, ombiSettings.DefaultLanguageCode);
|
if (plexSettings.Enable)
|
||||||
await ProcessEmbyMovies(embyMovies, sb, ombiSettings.DefaultLanguageCode);
|
{
|
||||||
|
await ProcessPlexMovies(plexMovies, sb, ombiSettings.DefaultLanguageCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (embySettings.Enable)
|
||||||
|
{
|
||||||
|
await ProcessEmbyMovies(embyMovies, sb, ombiSettings.DefaultLanguageCode);
|
||||||
|
}
|
||||||
|
|
||||||
sb.Append("</tr>");
|
sb.Append("</tr>");
|
||||||
sb.Append("</table>");
|
sb.Append("</table>");
|
||||||
sb.Append("</td>");
|
sb.Append("</td>");
|
||||||
|
@ -367,8 +378,16 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
|
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||||
sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">");
|
sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">");
|
||||||
sb.Append("<tr>");
|
sb.Append("<tr>");
|
||||||
await ProcessPlexTv(plexEpisodes, sb);
|
if (plexSettings.Enable)
|
||||||
await ProcessEmbyTv(embyEp, sb);
|
{
|
||||||
|
await ProcessPlexTv(plexEpisodes, sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (embySettings.Enable)
|
||||||
|
{
|
||||||
|
await ProcessEmbyTv(embyEp, sb);
|
||||||
|
}
|
||||||
|
|
||||||
sb.Append("</tr>");
|
sb.Append("</tr>");
|
||||||
sb.Append("</table>");
|
sb.Append("</table>");
|
||||||
sb.Append("</td>");
|
sb.Append("</td>");
|
||||||
|
|
|
@ -5,18 +5,13 @@ using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Hangfire.Console;
|
|
||||||
using Hangfire.Server;
|
using Hangfire.Server;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
using Ombi.Api.Service;
|
|
||||||
using Ombi.Api.Service.Models;
|
|
||||||
using Ombi.Core.Processor;
|
using Ombi.Core.Processor;
|
||||||
using Ombi.Core.Settings;
|
using Ombi.Core.Settings;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
|
@ -40,7 +35,6 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
Settings = s;
|
Settings = s;
|
||||||
_processProvider = proc;
|
_processProvider = proc;
|
||||||
_appConfig = appConfig;
|
_appConfig = appConfig;
|
||||||
Settings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ILogger<OmbiAutomaticUpdater> Logger { get; }
|
private ILogger<OmbiAutomaticUpdater> Logger { get; }
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Ombi.Api.Emby;
|
||||||
using Ombi.Api.TheMovieDb;
|
using Ombi.Api.TheMovieDb;
|
||||||
using Ombi.Api.TheMovieDb.Models;
|
using Ombi.Api.TheMovieDb.Models;
|
||||||
using Ombi.Api.TvMaze;
|
using Ombi.Api.TvMaze;
|
||||||
|
@ -21,7 +22,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
{
|
{
|
||||||
public RefreshMetadata(IPlexContentRepository plexRepo, IEmbyContentRepository embyRepo,
|
public RefreshMetadata(IPlexContentRepository plexRepo, IEmbyContentRepository embyRepo,
|
||||||
ILogger<RefreshMetadata> log, ITvMazeApi tvApi, ISettingsService<PlexSettings> plexSettings,
|
ILogger<RefreshMetadata> log, ITvMazeApi tvApi, ISettingsService<PlexSettings> plexSettings,
|
||||||
IMovieDbApi movieApi, ISettingsService<EmbySettings> embySettings, IPlexAvailabilityChecker plexAvailability, IEmbyAvaliabilityChecker embyAvaliability)
|
IMovieDbApi movieApi, ISettingsService<EmbySettings> embySettings, IPlexAvailabilityChecker plexAvailability, IEmbyAvaliabilityChecker embyAvaliability,
|
||||||
|
IEmbyApi embyApi)
|
||||||
{
|
{
|
||||||
_plexRepo = plexRepo;
|
_plexRepo = plexRepo;
|
||||||
_embyRepo = embyRepo;
|
_embyRepo = embyRepo;
|
||||||
|
@ -32,6 +34,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
_embySettings = embySettings;
|
_embySettings = embySettings;
|
||||||
_plexAvailabilityChecker = plexAvailability;
|
_plexAvailabilityChecker = plexAvailability;
|
||||||
_embyAvaliabilityChecker = embyAvaliability;
|
_embyAvaliabilityChecker = embyAvaliability;
|
||||||
|
_embyApi = embyApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IPlexContentRepository _plexRepo;
|
private readonly IPlexContentRepository _plexRepo;
|
||||||
|
@ -43,6 +46,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
private readonly ITvMazeApi _tvApi;
|
private readonly ITvMazeApi _tvApi;
|
||||||
private readonly ISettingsService<PlexSettings> _plexSettings;
|
private readonly ISettingsService<PlexSettings> _plexSettings;
|
||||||
private readonly ISettingsService<EmbySettings> _embySettings;
|
private readonly ISettingsService<EmbySettings> _embySettings;
|
||||||
|
private readonly IEmbyApi _embyApi;
|
||||||
|
|
||||||
public async Task Start()
|
public async Task Start()
|
||||||
{
|
{
|
||||||
|
@ -54,11 +58,11 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
{
|
{
|
||||||
await StartPlex();
|
await StartPlex();
|
||||||
}
|
}
|
||||||
|
|
||||||
var embySettings = await _embySettings.GetSettingsAsync();
|
var embySettings = await _embySettings.GetSettingsAsync();
|
||||||
if (embySettings.Enable)
|
if (embySettings.Enable)
|
||||||
{
|
{
|
||||||
await StartEmby();
|
await StartEmby(embySettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -123,9 +127,9 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
await StartPlexTv(allTv);
|
await StartPlexTv(allTv);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StartEmby()
|
private async Task StartEmby(EmbySettings s)
|
||||||
{
|
{
|
||||||
await StartEmbyMovies();
|
await StartEmbyMovies(s);
|
||||||
await StartEmbyTv();
|
await StartEmbyTv();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +162,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
_plexRepo.UpdateWithoutSave(show);
|
_plexRepo.UpdateWithoutSave(show);
|
||||||
}
|
}
|
||||||
tvCount++;
|
tvCount++;
|
||||||
if (tvCount >= 20)
|
if (tvCount >= 75)
|
||||||
{
|
{
|
||||||
await _plexRepo.SaveChangesAsync();
|
await _plexRepo.SaveChangesAsync();
|
||||||
tvCount = 0;
|
tvCount = 0;
|
||||||
|
@ -198,7 +202,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
_embyRepo.UpdateWithoutSave(show);
|
_embyRepo.UpdateWithoutSave(show);
|
||||||
}
|
}
|
||||||
tvCount++;
|
tvCount++;
|
||||||
if (tvCount >= 20)
|
if (tvCount >= 75)
|
||||||
{
|
{
|
||||||
await _embyRepo.SaveChangesAsync();
|
await _embyRepo.SaveChangesAsync();
|
||||||
tvCount = 0;
|
tvCount = 0;
|
||||||
|
@ -229,7 +233,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
_plexRepo.UpdateWithoutSave(movie);
|
_plexRepo.UpdateWithoutSave(movie);
|
||||||
}
|
}
|
||||||
movieCount++;
|
movieCount++;
|
||||||
if (movieCount >= 20)
|
if (movieCount >= 75)
|
||||||
{
|
{
|
||||||
await _plexRepo.SaveChangesAsync();
|
await _plexRepo.SaveChangesAsync();
|
||||||
movieCount = 0;
|
movieCount = 0;
|
||||||
|
@ -239,31 +243,56 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
await _plexRepo.SaveChangesAsync();
|
await _plexRepo.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StartEmbyMovies()
|
private async Task StartEmbyMovies(EmbySettings settings)
|
||||||
{
|
{
|
||||||
var allMovies = _embyRepo.GetAll().Where(x =>
|
var allMovies = _embyRepo.GetAll().Where(x =>
|
||||||
x.Type == EmbyMediaType.Movie && (!x.TheMovieDbId.HasValue() || !x.ImdbId.HasValue()));
|
x.Type == EmbyMediaType.Movie && (!x.TheMovieDbId.HasValue() || !x.ImdbId.HasValue()));
|
||||||
int movieCount = 0;
|
int movieCount = 0;
|
||||||
foreach (var movie in allMovies)
|
foreach (var movie in allMovies)
|
||||||
{
|
{
|
||||||
var hasImdb = movie.ImdbId.HasValue();
|
movie.ImdbId.HasValue();
|
||||||
var hasTheMovieDb = movie.TheMovieDbId.HasValue();
|
movie.TheMovieDbId.HasValue();
|
||||||
// Movies don't really use TheTvDb
|
// Movies don't really use TheTvDb
|
||||||
|
|
||||||
if (!hasImdb)
|
// Check if it even has 1 ID
|
||||||
|
if (!movie.HasImdb && !movie.HasTheMovieDb)
|
||||||
{
|
{
|
||||||
var imdbId = await GetImdbId(hasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty);
|
// Ok this sucks,
|
||||||
|
// The only think I can think that has happened is that we scanned Emby before Emby has got the metadata
|
||||||
|
// So let's recheck emby to see if they have got the metadata now
|
||||||
|
_log.LogInformation($"Movie {movie.Title} does not have a ImdbId or TheMovieDbId, so rechecking emby");
|
||||||
|
foreach (var server in settings.Servers)
|
||||||
|
{
|
||||||
|
_log.LogInformation($"Checking server {server.Name} for upto date metadata");
|
||||||
|
var movieInfo = await _embyApi.GetMovieInformation(movie.EmbyId, server.ApiKey, server.AdministratorId,
|
||||||
|
server.FullUri);
|
||||||
|
|
||||||
|
if (movieInfo.ProviderIds?.Imdb.HasValue() ?? false)
|
||||||
|
{
|
||||||
|
movie.ImdbId = movieInfo.ProviderIds.Imdb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (movieInfo.ProviderIds?.Tmdb.HasValue() ?? false)
|
||||||
|
{
|
||||||
|
movie.TheMovieDbId = movieInfo.ProviderIds.Tmdb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!movie.HasImdb)
|
||||||
|
{
|
||||||
|
var imdbId = await GetImdbId(movie.HasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty);
|
||||||
movie.ImdbId = imdbId;
|
movie.ImdbId = imdbId;
|
||||||
_embyRepo.UpdateWithoutSave(movie);
|
_embyRepo.UpdateWithoutSave(movie);
|
||||||
}
|
}
|
||||||
if (!hasTheMovieDb)
|
if (!movie.HasTheMovieDb)
|
||||||
{
|
{
|
||||||
var id = await GetTheMovieDbId(false, hasImdb, string.Empty, movie.ImdbId, movie.Title, true);
|
var id = await GetTheMovieDbId(false, movie.HasImdb, string.Empty, movie.ImdbId, movie.Title, true);
|
||||||
movie.TheMovieDbId = id;
|
movie.TheMovieDbId = id;
|
||||||
_embyRepo.UpdateWithoutSave(movie);
|
_embyRepo.UpdateWithoutSave(movie);
|
||||||
}
|
}
|
||||||
movieCount++;
|
movieCount++;
|
||||||
if (movieCount >= 20)
|
if (movieCount >= 75)
|
||||||
{
|
{
|
||||||
await _embyRepo.SaveChangesAsync();
|
await _embyRepo.SaveChangesAsync();
|
||||||
movieCount = 0;
|
movieCount = 0;
|
||||||
|
|
|
@ -20,8 +20,6 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
_email = provider;
|
_email = provider;
|
||||||
_templates = template;
|
_templates = template;
|
||||||
_customizationSettings = c;
|
_customizationSettings = c;
|
||||||
email.ClearCache();
|
|
||||||
_customizationSettings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ISettingsService<EmailNotificationSettings> _emailSettings;
|
private readonly ISettingsService<EmailNotificationSettings> _emailSettings;
|
||||||
|
|
|
@ -57,7 +57,6 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
EpisodeSync = epsiodeSync;
|
EpisodeSync = epsiodeSync;
|
||||||
Metadata = metadataRefresh;
|
Metadata = metadataRefresh;
|
||||||
Checker = checker;
|
Checker = checker;
|
||||||
plex.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISettingsService<PlexSettings> Plex { get; }
|
private ISettingsService<PlexSettings> Plex { get; }
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
_api = plexApi;
|
_api = plexApi;
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_availabilityChecker = a;
|
_availabilityChecker = a;
|
||||||
_settings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ISettingsService<PlexSettings> _settings;
|
private readonly ISettingsService<PlexSettings> _settings;
|
||||||
|
|
|
@ -24,8 +24,6 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
_log = log;
|
_log = log;
|
||||||
_plexSettings = plexSettings;
|
_plexSettings = plexSettings;
|
||||||
_userManagementSettings = ums;
|
_userManagementSettings = ums;
|
||||||
_userManagementSettings.ClearCache();
|
|
||||||
_plexSettings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IPlexApi _api;
|
private readonly IPlexApi _api;
|
||||||
|
|
|
@ -22,7 +22,6 @@ namespace Ombi.Schedule.Jobs.Radarr
|
||||||
RadarrApi = radarrApi;
|
RadarrApi = radarrApi;
|
||||||
Logger = log;
|
Logger = log;
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
RadarrSettings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISettingsService<RadarrSettings> RadarrSettings { get; }
|
private ISettingsService<RadarrSettings> RadarrSettings { get; }
|
||||||
|
|
|
@ -22,7 +22,6 @@ namespace Ombi.Schedule.Jobs.SickRage
|
||||||
_api = api;
|
_api = api;
|
||||||
_log = l;
|
_log = l;
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
_settings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ISettingsService<SickRageSettings> _settings;
|
private readonly ISettingsService<SickRageSettings> _settings;
|
||||||
|
|
|
@ -25,7 +25,6 @@ namespace Ombi.Schedule.Jobs.Sonarr
|
||||||
_api = api;
|
_api = api;
|
||||||
_log = l;
|
_log = l;
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
_settings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ISettingsService<SonarrSettings> _settings;
|
private readonly ISettingsService<SonarrSettings> _settings;
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace Ombi.Settings.Settings
|
||||||
var model = obj;
|
var model = obj;
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}, DateTime.Now.AddHours(2));
|
}, DateTime.Now.AddHours(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SaveSettings(T model)
|
public bool SaveSettings(T model)
|
||||||
|
|
|
@ -87,53 +87,6 @@ namespace Ombi.Store.Context
|
||||||
|
|
||||||
public void Seed()
|
public void Seed()
|
||||||
{
|
{
|
||||||
// VACUUM;
|
|
||||||
Database.ExecuteSqlCommand("VACUUM;");
|
|
||||||
|
|
||||||
// Make sure we have the roles
|
|
||||||
var newsletterRole = Roles.Where(x => x.Name == OmbiRoles.ReceivesNewsletter);
|
|
||||||
if (!newsletterRole.Any())
|
|
||||||
{
|
|
||||||
Roles.Add(new IdentityRole(OmbiRoles.ReceivesNewsletter)
|
|
||||||
{
|
|
||||||
NormalizedName = OmbiRoles.ReceivesNewsletter.ToUpper()
|
|
||||||
});
|
|
||||||
SaveChanges();
|
|
||||||
}
|
|
||||||
var requestMusicRole = Roles.Where(x => x.Name == OmbiRoles.RequestMusic);
|
|
||||||
if (!requestMusicRole.Any())
|
|
||||||
{
|
|
||||||
Roles.Add(new IdentityRole(OmbiRoles.RequestMusic)
|
|
||||||
{
|
|
||||||
NormalizedName = OmbiRoles.RequestMusic.ToUpper()
|
|
||||||
});
|
|
||||||
Roles.Add(new IdentityRole(OmbiRoles.AutoApproveMusic)
|
|
||||||
{
|
|
||||||
NormalizedName = OmbiRoles.AutoApproveMusic.ToUpper()
|
|
||||||
});
|
|
||||||
SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
var manageOwnRequestsRole = Roles.Where(x => x.Name == OmbiRoles.ManageOwnRequests);
|
|
||||||
if (!manageOwnRequestsRole.Any())
|
|
||||||
{
|
|
||||||
Roles.Add(new IdentityRole(OmbiRoles.ManageOwnRequests)
|
|
||||||
{
|
|
||||||
NormalizedName = OmbiRoles.ManageOwnRequests.ToUpper()
|
|
||||||
});
|
|
||||||
SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
var editCustomPage = Roles.Where(x => x.Name == OmbiRoles.EditCustomPage);
|
|
||||||
if (!editCustomPage.Any())
|
|
||||||
{
|
|
||||||
Roles.Add(new IdentityRole(OmbiRoles.EditCustomPage)
|
|
||||||
{
|
|
||||||
NormalizedName = OmbiRoles.EditCustomPage.ToUpper()
|
|
||||||
});
|
|
||||||
SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we have the API User
|
// Make sure we have the API User
|
||||||
var apiUserExists = Users.Any(x => x.UserName.Equals("Api", StringComparison.CurrentCultureIgnoreCase));
|
var apiUserExists = Users.Any(x => x.UserName.Equals("Api", StringComparison.CurrentCultureIgnoreCase));
|
||||||
if (!apiUserExists)
|
if (!apiUserExists)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Globalization;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Entities.Requests;
|
using Ombi.Store.Entities.Requests;
|
||||||
|
|
||||||
|
@ -27,9 +28,10 @@ namespace Ombi.Store.Repository.Requests
|
||||||
public bool Approved { get; set; }
|
public bool Approved { get; set; }
|
||||||
public bool Requested { get; set; }
|
public bool Requested { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public int SeasonId { get; set; }
|
public int SeasonId { get; set; }
|
||||||
[ForeignKey(nameof(SeasonId))]
|
[ForeignKey(nameof(SeasonId))]
|
||||||
public SeasonRequests Season { get; set; }
|
public SeasonRequests Season { get; set; }
|
||||||
|
|
||||||
|
[NotMapped] public string AirDateDisplay => AirDate == DateTime.MinValue ? "Unknown" : AirDate.ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,10 +17,6 @@ namespace Ombi.Store.Entities.Requests
|
||||||
public DateTime ReleaseDate { get; set; }
|
public DateTime ReleaseDate { get; set; }
|
||||||
public string Status { get; set; }
|
public string Status { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is so we can correctly send the right amount of seasons to Sonarr
|
|
||||||
/// </summary>
|
|
||||||
[NotMapped]
|
|
||||||
public int TotalSeasons { get; set; }
|
public int TotalSeasons { get; set; }
|
||||||
|
|
||||||
public List<ChildRequests> ChildRequests { get; set; }
|
public List<ChildRequests> ChildRequests { get; set; }
|
||||||
|
|
1212
src/Ombi.Store/Migrations/20190216224539_Roles.Designer.cs
generated
Normal file
1212
src/Ombi.Store/Migrations/20190216224539_Roles.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
32
src/Ombi.Store/Migrations/20190216224539_Roles.cs
Normal file
32
src/Ombi.Store/Migrations/20190216224539_Roles.cs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Ombi.Helpers;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations
|
||||||
|
{
|
||||||
|
public partial class Roles : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder mb)
|
||||||
|
{
|
||||||
|
// Make sure we have the roles
|
||||||
|
InsertRole(mb, OmbiRoles.ReceivesNewsletter);
|
||||||
|
InsertRole(mb, OmbiRoles.RequestMusic);
|
||||||
|
InsertRole(mb, OmbiRoles.AutoApproveMusic);
|
||||||
|
InsertRole(mb, OmbiRoles.ManageOwnRequests);
|
||||||
|
InsertRole(mb, OmbiRoles.EditCustomPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InsertRole(MigrationBuilder mb, string role)
|
||||||
|
{
|
||||||
|
mb.Sql($@"
|
||||||
|
INSERT INTO AspnetRoles(Id, ConcurrencyStamp, Name, NormalizedName)
|
||||||
|
SELECT '{Guid.NewGuid().ToString()}','{Guid.NewGuid().ToString()}','{role}', '{role.ToUpper()}'
|
||||||
|
WHERE NOT EXISTS(SELECT 1 FROM AspnetRoles WHERE Name = '{role}');");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1214
src/Ombi.Store/Migrations/20190216231519_TvRequestsTotalSeasons.Designer.cs
generated
Normal file
1214
src/Ombi.Store/Migrations/20190216231519_TvRequestsTotalSeasons.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,23 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Migrations
|
||||||
|
{
|
||||||
|
public partial class TvRequestsTotalSeasons : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "TotalSeasons",
|
||||||
|
table: "TvRequests",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "TotalSeasons",
|
||||||
|
table: "TvRequests");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -819,6 +819,8 @@ namespace Ombi.Store.Migrations
|
||||||
|
|
||||||
b.Property<string>("Title");
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<int>("TotalSeasons");
|
||||||
|
|
||||||
b.Property<int>("TvDbId");
|
b.Property<int>("TvDbId");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
|
@ -146,6 +146,7 @@ export interface IEpisodesRequests {
|
||||||
episodeNumber: number;
|
episodeNumber: number;
|
||||||
title: string;
|
title: string;
|
||||||
airDate: Date;
|
airDate: Date;
|
||||||
|
airDateDisplay: string;
|
||||||
url: string;
|
url: string;
|
||||||
available: boolean;
|
available: boolean;
|
||||||
requested: boolean;
|
requested: boolean;
|
||||||
|
|
|
@ -42,8 +42,11 @@
|
||||||
<td>
|
<td>
|
||||||
{{ep.title}}
|
{{ep.title}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td *ngIf="ep.airDateDisplay != 'Unknown'">
|
||||||
{{ep.airDate | amLocal | amDateFormat: 'L' }}
|
{{ep.airDate | amLocal | amDateFormat: 'L' }}
|
||||||
|
</td>
|
||||||
|
<td *ngIf="ep.airDateDisplay == 'Unknown'">
|
||||||
|
{{ep.airDateDisplay }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<ng-template [ngIf]="ep.available"><span class="label label-success" id="availableLabel">Available</span></ng-template>
|
<ng-template [ngIf]="ep.available"><span class="label label-success" id="availableLabel">Available</span></ng-template>
|
||||||
|
|
|
@ -15,4 +15,8 @@ export class MobileService extends ServiceHelpers {
|
||||||
public getUserDeviceList(): Observable<IMobileUsersViewModel[]> {
|
public getUserDeviceList(): Observable<IMobileUsersViewModel[]> {
|
||||||
return this.http.get<IMobileUsersViewModel[]>(`${this.url}notification/`, {headers: this.headers});
|
return this.http.get<IMobileUsersViewModel[]>(`${this.url}notification/`, {headers: this.headers});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public deleteUser(userId: string): Observable<boolean> {
|
||||||
|
return this.http.post<boolean>(`${this.url}remove/`, userId, {headers: this.headers});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<span>Discord</span>
|
<span>Discord</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="https://discord.gg/Sa7wNWb" target="_blank">https://discord.gg/</a>
|
<a href="https://discord.gg/Sa7wNWb" target="_blank">https://discord.gg/Sa7wNWb</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="select" class="control-label">User to send test notification to</label>
|
<label for="select" class="control-label">Users</label>
|
||||||
<div>
|
<div>
|
||||||
<select class="form-control form-control-custom" id="select" [(ngModel)]="testUserId" [ngModelOptions]="{standalone: true}">
|
<select class="form-control form-control-custom" id="select" [(ngModel)]="testUserId" [ngModelOptions]="{standalone: true}">
|
||||||
<option value="">Please select</option>
|
<option value="">Please select</option>
|
||||||
|
@ -46,7 +46,12 @@
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div>
|
<div>
|
||||||
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-danger-outline">Test</button>
|
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-danger-outline">Send Test Notification</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<button [disabled]="form.invalid" type="button" (click)="remove(form)" class="btn btn-danger-outline">Remove User</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -79,4 +79,24 @@ export class MobileComponent implements OnInit {
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public remove() {
|
||||||
|
if (!this.testUserId) {
|
||||||
|
this.notificationService.warning("Warning", "Please select a user to remove");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mobileService.deleteUser(this.testUserId).subscribe(x => {
|
||||||
|
if (x) {
|
||||||
|
this.notificationService.success("Removed users notification");
|
||||||
|
const userToRemove = this.userList.filter(u => {
|
||||||
|
return u.userId === this.testUserId;
|
||||||
|
})[1];
|
||||||
|
this.userList.splice(this.userList.indexOf(userToRemove),1);
|
||||||
|
} else {
|
||||||
|
this.notificationService.error("There was an error when removing the notification. Please check your logs");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ namespace Ombi.Controllers.V1.External
|
||||||
RadarrApi = radarr;
|
RadarrApi = radarr;
|
||||||
RadarrSettings = settings;
|
RadarrSettings = settings;
|
||||||
Cache = mem;
|
Cache = mem;
|
||||||
RadarrSettings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRadarrApi RadarrApi { get; }
|
private IRadarrApi RadarrApi { get; }
|
||||||
|
|
|
@ -21,7 +21,6 @@ namespace Ombi.Controllers.V1.External
|
||||||
SonarrApi = sonarr;
|
SonarrApi = sonarr;
|
||||||
SonarrV3Api = sonarrv3;
|
SonarrV3Api = sonarrv3;
|
||||||
SonarrSettings = settings;
|
SonarrSettings = settings;
|
||||||
SonarrSettings.ClearCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISonarrApi SonarrApi { get; }
|
private ISonarrApi SonarrApi { get; }
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace Ombi.Controllers.V1
|
||||||
public async Task<int> CreateIssue([FromBody]Issues i)
|
public async Task<int> CreateIssue([FromBody]Issues i)
|
||||||
{
|
{
|
||||||
i.IssueCategory = null;
|
i.IssueCategory = null;
|
||||||
i.UserReportedId = (await _userManager.Users.FirstOrDefaultAsync(x => x.UserName == User.Identity.Name)).Id;
|
i.UserReportedId = (await _userManager.Users.FirstOrDefaultAsync(x => x.UserName.Equals(User.Identity.Name, StringComparison.InvariantCultureIgnoreCase))).Id;
|
||||||
await _issues.Add(i);
|
await _issues.Add(i);
|
||||||
var category = await _categories.GetAll().FirstOrDefaultAsync(x => i.IssueCategoryId == x.Id);
|
var category = await _categories.GetAll().FirstOrDefaultAsync(x => i.IssueCategoryId == x.Id);
|
||||||
if (category != null)
|
if (category != null)
|
||||||
|
@ -197,7 +197,7 @@ namespace Ombi.Controllers.V1
|
||||||
[HttpPost("comments")]
|
[HttpPost("comments")]
|
||||||
public async Task<IssueComments> AddComment([FromBody] NewIssueCommentViewModel comment)
|
public async Task<IssueComments> AddComment([FromBody] NewIssueCommentViewModel comment)
|
||||||
{
|
{
|
||||||
var user = await _userManager.Users.Where(x => User.Identity.Name == x.UserName)
|
var user = await _userManager.Users.Where(x => User.Identity.Name.Equals(x.UserName, StringComparison.InvariantCultureIgnoreCase))
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
var issue = await _issues.GetAll().Include(x => x.UserReported).Include(x => x.IssueCategory).FirstOrDefaultAsync(x => x.Id == comment.IssueId);
|
var issue = await _issues.GetAll().Include(x => x.UserReported).Include(x => x.IssueCategory).FirstOrDefaultAsync(x => x.Id == comment.IssueId);
|
||||||
if (issue == null)
|
if (issue == null)
|
||||||
|
@ -256,7 +256,7 @@ namespace Ombi.Controllers.V1
|
||||||
[HttpPost("status")]
|
[HttpPost("status")]
|
||||||
public async Task<bool> UpdateStatus([FromBody] IssueStateViewModel model)
|
public async Task<bool> UpdateStatus([FromBody] IssueStateViewModel model)
|
||||||
{
|
{
|
||||||
var user = await _userManager.Users.Where(x => User.Identity.Name == x.UserName)
|
var user = await _userManager.Users.Where(x => User.Identity.Name.Equals(x.UserName, StringComparison.InvariantCultureIgnoreCase))
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
var issue = await _issues.GetAll().Include(x => x.UserReported).Include(x => x.IssueCategory).FirstOrDefaultAsync(x => x.Id == model.IssueId);
|
var issue = await _issues.GetAll().Include(x => x.UserReported).Include(x => x.IssueCategory).FirstOrDefaultAsync(x => x.Id == model.IssueId);
|
||||||
if (issue == null)
|
if (issue == null)
|
||||||
|
@ -265,6 +265,11 @@ namespace Ombi.Controllers.V1
|
||||||
}
|
}
|
||||||
|
|
||||||
issue.Status = model.Status;
|
issue.Status = model.Status;
|
||||||
|
|
||||||
|
if (model.Status == IssueStatus.Resolved)
|
||||||
|
{
|
||||||
|
issue.ResovledDate = DateTime.UtcNow;
|
||||||
|
}
|
||||||
await _issues.SaveChangesAsync();
|
await _issues.SaveChangesAsync();
|
||||||
|
|
||||||
if (issue.Status == IssueStatus.Resolved)
|
if (issue.Status == IssueStatus.Resolved)
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Ombi.Attributes;
|
using Ombi.Attributes;
|
||||||
using Ombi.Core.Authentication;
|
using Ombi.Core.Authentication;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
|
@ -20,14 +21,16 @@ namespace Ombi.Controllers.V1
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class MobileController : ControllerBase
|
public class MobileController : ControllerBase
|
||||||
{
|
{
|
||||||
public MobileController(IRepository<NotificationUserId> notification, OmbiUserManager user)
|
public MobileController(IRepository<NotificationUserId> notification, OmbiUserManager user, ILogger<MobileController> log)
|
||||||
{
|
{
|
||||||
_notification = notification;
|
_notification = notification;
|
||||||
_userManager = user;
|
_userManager = user;
|
||||||
|
_log = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IRepository<NotificationUserId> _notification;
|
private readonly IRepository<NotificationUserId> _notification;
|
||||||
private readonly OmbiUserManager _userManager;
|
private readonly OmbiUserManager _userManager;
|
||||||
|
private readonly ILogger _log;
|
||||||
|
|
||||||
[HttpPost("Notification")]
|
[HttpPost("Notification")]
|
||||||
[ApiExplorerSettings(IgnoreApi = true)]
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
|
@ -78,5 +81,24 @@ namespace Ombi.Controllers.V1
|
||||||
}
|
}
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
|
[Admin]
|
||||||
|
public async Task<bool> RemoveUser([FromBody] string userId)
|
||||||
|
{
|
||||||
|
var user = await _userManager.Users.Include(x => x.NotificationUserIds).FirstOrDefaultAsync(x => x.Id.Equals(userId, StringComparison.InvariantCultureIgnoreCase));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _notification.DeleteRange(user.NotificationUserIds);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_log.LogError(e, "Could not delete user notification");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
41
src/Ombi/package-lock.json
generated
41
src/Ombi/package-lock.json
generated
|
@ -4190,7 +4190,8 @@
|
||||||
},
|
},
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"aproba": {
|
"aproba": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
|
@ -4208,11 +4209,13 @@
|
||||||
},
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
|
@ -4225,15 +4228,18 @@
|
||||||
},
|
},
|
||||||
"code-point-at": {
|
"code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
|
@ -4336,7 +4342,8 @@
|
||||||
},
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
|
@ -4346,6 +4353,7 @@
|
||||||
"is-fullwidth-code-point": {
|
"is-fullwidth-code-point": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
}
|
}
|
||||||
|
@ -4358,17 +4366,20 @@
|
||||||
"minimatch": {
|
"minimatch": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.0"
|
"yallist": "^3.0.0"
|
||||||
|
@ -4385,6 +4396,7 @@
|
||||||
"mkdirp": {
|
"mkdirp": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
|
@ -4457,7 +4469,8 @@
|
||||||
},
|
},
|
||||||
"number-is-nan": {
|
"number-is-nan": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
|
@ -4467,6 +4480,7 @@
|
||||||
"once": {
|
"once": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
|
@ -4542,7 +4556,8 @@
|
||||||
},
|
},
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
|
@ -4572,6 +4587,7 @@
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
|
@ -4589,6 +4605,7 @@
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-regex": "^2.0.0"
|
"ansi-regex": "^2.0.0"
|
||||||
}
|
}
|
||||||
|
@ -4627,11 +4644,13 @@
|
||||||
},
|
},
|
||||||
"wrappy": {
|
"wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
"GridTitle": "Título",
|
"GridTitle": "Título",
|
||||||
"AirDate": "Fecha de estreno",
|
"AirDate": "Fecha de estreno",
|
||||||
"GridStatus": "Estado",
|
"GridStatus": "Estado",
|
||||||
"ReportIssue": "Informar de un problema/error",
|
"ReportIssue": "Informar de Problema",
|
||||||
"Filter": "Filtrar",
|
"Filter": "Filtrar",
|
||||||
"Sort": "Ordenar",
|
"Sort": "Ordenar",
|
||||||
"SeasonNumberHeading": "Temporada: {seasonNumber}",
|
"SeasonNumberHeading": "Temporada: {seasonNumber}",
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
"ContinueButton": "Doorgaan",
|
"ContinueButton": "Doorgaan",
|
||||||
"Available": "Beschikbaar",
|
"Available": "Beschikbaar",
|
||||||
"PartiallyAvailable": "Deels Beschikbaar",
|
"PartiallyAvailable": "Deels Beschikbaar",
|
||||||
"Monitored": "Gecontroleerd",
|
"Monitored": "Onder toezicht",
|
||||||
"NotAvailable": "Niet Beschikbaar",
|
"NotAvailable": "Niet Beschikbaar",
|
||||||
"ProcessingRequest": "Verzoek wordt verwerkt",
|
"ProcessingRequest": "Verzoek wordt verwerkt",
|
||||||
"PendingApproval": "Wacht op goedkeuring",
|
"PendingApproval": "Wacht op goedkeuring",
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
"Requests": "Solicitações",
|
"Requests": "Solicitações",
|
||||||
"UserManagement": "Gerenciador de Usuário",
|
"UserManagement": "Gerenciador de Usuário",
|
||||||
"Issues": "Problemas",
|
"Issues": "Problemas",
|
||||||
"Vote": "Vote",
|
"Vote": "Votar",
|
||||||
"Donate": "Fazer uma doação!",
|
"Donate": "Fazer uma doação!",
|
||||||
"DonateLibraryMaintainer": "Doar para o Dono da Biblioteca",
|
"DonateLibraryMaintainer": "Doar para o Dono da Biblioteca",
|
||||||
"DonateTooltip": "É assim que eu convenço a minha mulher a deixar-me passar o meu tempo livre desenvolvendo Ombi;)",
|
"DonateTooltip": "É assim que eu convenço a minha mulher a deixar-me passar o meu tempo livre desenvolvendo Ombi;)",
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
"ViewOnEmby": "Assistir no Emby",
|
"ViewOnEmby": "Assistir no Emby",
|
||||||
"RequestAdded": "Pedido de {{title}} foi adicionado com sucesso",
|
"RequestAdded": "Pedido de {{title}} foi adicionado com sucesso",
|
||||||
"Similar": "Semelhante",
|
"Similar": "Semelhante",
|
||||||
"Refine": "Refine",
|
"Refine": "Filtro",
|
||||||
"Movies": {
|
"Movies": {
|
||||||
"PopularMovies": "Filmes populares",
|
"PopularMovies": "Filmes populares",
|
||||||
"UpcomingMovies": "Próximos filmes",
|
"UpcomingMovies": "Próximos filmes",
|
||||||
|
@ -137,11 +137,11 @@
|
||||||
"SortStatusAsc": "Status ▲",
|
"SortStatusAsc": "Status ▲",
|
||||||
"SortStatusDesc": "Status ▼",
|
"SortStatusDesc": "Status ▼",
|
||||||
"Remaining": {
|
"Remaining": {
|
||||||
"Quota": "{{remaining}}/{{total}} requests remaining",
|
"Quota": "{{remaining}}/{{total}} solicitações restantes",
|
||||||
"NextDays": "Another request will be added in {{time}} days",
|
"NextDays": "Outro pedido será adicionado em {{time}} dias",
|
||||||
"NextHours": "Another request will be added in {{time}} hours",
|
"NextHours": "Outro pedido será adicionado em {{time}} horas",
|
||||||
"NextMinutes": "Another request will be added in {{time}} minutes",
|
"NextMinutes": "Outro pedido será adicionado em {{time}} minutos",
|
||||||
"NextMinute": "Another request will be added in {{time}} minute"
|
"NextMinute": "Outro pedido será adicionado em {{time}} minuto"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Issues": {
|
"Issues": {
|
||||||
|
@ -171,15 +171,15 @@
|
||||||
"PendingApproval": "Aprovação Pendente"
|
"PendingApproval": "Aprovação Pendente"
|
||||||
},
|
},
|
||||||
"UserManagment": {
|
"UserManagment": {
|
||||||
"TvRemaining": "TV: {{remaining}}/{{total}} remaining",
|
"TvRemaining": "Tv: {{remaining}}/{{total}} restantes",
|
||||||
"MovieRemaining": "Movies: {{remaining}}/{{total}} remaining",
|
"MovieRemaining": "Filmes: {{remaining}}/{{total}} restantes",
|
||||||
"MusicRemaining": "Music: {{remaining}}/{{total}} remaining",
|
"MusicRemaining": "Música: {{remaining}}/{{total}} restantes",
|
||||||
"TvDue": "TV: {{date}}",
|
"TvDue": "TV: {{date}}",
|
||||||
"MovieDue": "Movie: {{date}}",
|
"MovieDue": "Filme: {{date}}",
|
||||||
"MusicDue": "Music: {{date}}"
|
"MusicDue": "Música: {{date}}"
|
||||||
},
|
},
|
||||||
"Votes": {
|
"Votes": {
|
||||||
"CompletedVotesTab": "Voted",
|
"CompletedVotesTab": "Votado",
|
||||||
"VotesTab": "Votes Needed"
|
"VotesTab": "Votos necessários"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue