Your ROOT_URL in app.ini is https://git.cloudchain.link/ but you are visiting https://dash.bss.nz/open-source-mirrors/Ombi/commit/0f98f127561f439f14e459c5386c05ad8d7287b5 You should set ROOT_URL correctly, otherwise the web may not work correctly.
tidusjar 9 years ago
commit 0f98f12756

@ -0,0 +1,39 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: INotificationEngine.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System.Collections.Generic;
using System.Threading.Tasks;
using PlexRequests.Store;
namespace PlexRequests.Services.Interfaces
{
public interface INotificationEngine
{
Task NotifyUsers(IEnumerable<RequestedModel> modelChanged, string apiKey);
Task NotifyUsers(RequestedModel modelChanged, string apiKey);
}
}

@ -53,7 +53,7 @@ namespace PlexRequests.Services.Jobs
public class PlexAvailabilityChecker : IJob, IAvailabilityChecker
{
public PlexAvailabilityChecker(ISettingsService<PlexSettings> plexSettings, IRequestService request, IPlexApi plex, ICacheProvider cache,
INotificationService notify, IJobRecord rec, IRepository<UsersToNotify> users, IRepository<PlexEpisodes> repo)
INotificationService notify, IJobRecord rec, IRepository<UsersToNotify> users, IRepository<PlexEpisodes> repo, INotificationEngine e)
{
Plex = plexSettings;
RequestService = request;
@ -63,6 +63,7 @@ namespace PlexRequests.Services.Jobs
Job = rec;
UserNotifyRepo = users;
EpisodeRepo = repo;
NotificationEngine = e;
}
private ISettingsService<PlexSettings> Plex { get; }
@ -74,6 +75,9 @@ namespace PlexRequests.Services.Jobs
private INotificationService Notification { get; }
private IJobRecord Job { get; }
private IRepository<UsersToNotify> UserNotifyRepo { get; }
private INotificationEngine NotificationEngine { get; }
public void CheckAndUpdateAll()
{
var plexSettings = Plex.GetSettings();
@ -148,7 +152,7 @@ namespace PlexRequests.Services.Jobs
if (modifiedModel.Any())
{
NotifyUsers(modifiedModel, plexSettings.PlexAuthToken);
NotificationEngine.NotifyUsers(modifiedModel, plexSettings.PlexAuthToken);
RequestService.BatchUpdate(modifiedModel);
}
@ -489,63 +493,6 @@ namespace PlexRequests.Services.Jobs
return true;
}
private void NotifyUsers(IEnumerable<RequestedModel> modelChanged, string apiKey)
{
try
{
var plexUser = PlexApi.GetUsers(apiKey);
var userAccount = PlexApi.GetAccount(apiKey);
var adminUsername = userAccount.Username ?? string.Empty;
var users = UserNotifyRepo.GetAll().ToList();
Log.Debug("Notifying Users Count {0}", users.Count);
foreach (var model in modelChanged)
{
var selectedUsers = users.Select(x => x.Username).Intersect(model.RequestedUsers);
foreach (var user in selectedUsers)
{
Log.Info("Notifying user {0}", user);
if (user == adminUsername)
{
Log.Info("This user is the Plex server owner");
PublishUserNotification(userAccount.Username, userAccount.Email, model.Title);
return;
}
var email = plexUser.User.FirstOrDefault(x => x.Username == user);
if (email == null)
{
Log.Info("There is no email address for this Plex user, cannot send notification");
// We do not have a plex user that requested this!
continue;
}
Log.Info("Sending notification to: {0} at: {1}, for title: {2}", email.Username, email.Email, model.Title);
PublishUserNotification(email.Username, email.Email, model.Title);
}
}
}
catch (Exception e)
{
Log.Error(e);
}
}
private void PublishUserNotification(string username, string email, string title)
{
var notificationModel = new NotificationModel
{
User = username,
UserEmail = email,
NotificationType = NotificationType.RequestAvailable,
Title = title
};
// Send the notification to the user.
Notification.Publish(notificationModel);
}
public void Execute(IJobExecutionContext context)
{
try

@ -0,0 +1,156 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: NotificationEngine.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NLog;
using NLog.Fluent;
using PlexRequests.Api;
using PlexRequests.Api.Interfaces;
using PlexRequests.Core.Models;
using PlexRequests.Services.Interfaces;
using PlexRequests.Store;
using PlexRequests.Store.Models;
using PlexRequests.Store.Repository;
namespace PlexRequests.Services.Notification
{
public class NotificationEngine : INotificationEngine
{
public NotificationEngine(IPlexApi p, IRepository<UsersToNotify> repo, INotificationService service)
{
PlexApi = p;
UserNotifyRepo = repo;
Notification = service;
}
private IPlexApi PlexApi { get; }
private IRepository<UsersToNotify> UserNotifyRepo { get; }
private static Logger Log = LogManager.GetCurrentClassLogger();
private INotificationService Notification { get; }
public async Task NotifyUsers(IEnumerable<RequestedModel> modelChanged, string apiKey)
{
try
{
var plexUser = PlexApi.GetUsers(apiKey);
var userAccount = PlexApi.GetAccount(apiKey);
var adminUsername = userAccount.Username ?? string.Empty;
var users = UserNotifyRepo.GetAll().ToList();
Log.Debug("Notifying Users Count {0}", users.Count);
foreach (var model in modelChanged)
{
var selectedUsers = users.Select(x => x.Username).Intersect(model.RequestedUsers, StringComparer.CurrentCultureIgnoreCase);
foreach (var user in selectedUsers)
{
Log.Info("Notifying user {0}", user);
if (user.Equals(adminUsername, StringComparison.CurrentCultureIgnoreCase))
{
Log.Info("This user is the Plex server owner");
await PublishUserNotification(userAccount.Username, userAccount.Email, model.Title);
return;
}
var email = plexUser.User.FirstOrDefault(x => x.Username.Equals(user, StringComparison.CurrentCultureIgnoreCase));
if (email == null)
{
Log.Info("There is no email address for this Plex user, cannot send notification");
// We do not have a plex user that requested this!
continue;
}
Log.Info("Sending notification to: {0} at: {1}, for title: {2}", email.Username, email.Email, model.Title);
await PublishUserNotification(email.Username, email.Email, model.Title);
}
}
}
catch (Exception e)
{
Log.Error(e);
}
}
public async Task NotifyUsers(RequestedModel model, string apiKey)
{
try
{
var plexUser = PlexApi.GetUsers(apiKey);
var userAccount = PlexApi.GetAccount(apiKey);
var adminUsername = userAccount.Username ?? string.Empty;
var users = UserNotifyRepo.GetAll().ToList();
Log.Debug("Notifying Users Count {0}", users.Count);
var selectedUsers = users.Select(x => x.Username).Intersect(model.RequestedUsers, StringComparer.CurrentCultureIgnoreCase);
foreach (var user in selectedUsers)
{
Log.Info("Notifying user {0}", user);
if (user.Equals(adminUsername, StringComparison.CurrentCultureIgnoreCase))
{
Log.Info("This user is the Plex server owner");
await PublishUserNotification(userAccount.Username, userAccount.Email, model.Title);
return;
}
var email = plexUser.User.FirstOrDefault(x => x.Username.Equals(user, StringComparison.CurrentCultureIgnoreCase));
if (email == null)
{
Log.Info("There is no email address for this Plex user, cannot send notification");
// We do not have a plex user that requested this!
continue;
}
Log.Info("Sending notification to: {0} at: {1}, for title: {2}", email.Username, email.Email, model.Title);
await PublishUserNotification(email.Username, email.Email, model.Title);
}
}
catch (Exception e)
{
Log.Error(e);
}
}
private async Task PublishUserNotification(string username, string email, string title)
{
var notificationModel = new NotificationModel
{
User = username,
UserEmail = email,
NotificationType = NotificationType.RequestAvailable,
Title = title
};
// Send the notification to the user.
await Notification.Publish(notificationModel);
}
}
}

@ -75,6 +75,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Interfaces\IJobRecord.cs" />
<Compile Include="Interfaces\INotificationEngine.cs" />
<Compile Include="Jobs\JobRecord.cs" />
<Compile Include="Jobs\JobNames.cs" />
<Compile Include="Jobs\PlexEpisodeCacher.cs" />
@ -97,6 +98,7 @@
<Compile Include="Interfaces\INotification.cs" />
<Compile Include="Interfaces\INotificationService.cs" />
<Compile Include="Notification\EmailMessageNotification.cs" />
<Compile Include="Notification\NotificationEngine.cs" />
<Compile Include="Notification\NotificationModel.cs" />
<Compile Include="Notification\NotificationService.cs" />
<Compile Include="Notification\PushoverNotification.cs" />

@ -9,6 +9,7 @@
$scope.selectedUser = {}; // User on the right side
$scope.selectedClaims = {};
$scope.sortType = "username";
$scope.sortReverse = false;
$scope.searchTerm = "";
@ -27,20 +28,20 @@
// Get all users in the system
$scope.getUsers = function () {
$scope.users = userManagementService.getUsers()
.then(function (data) {
$scope.users = data.data;
});
.then(function (data) {
$scope.users = data.data;
});
};
// Get the claims and populate the create dropdown
$scope.getClaims = function () {
userManagementService.getClaims()
.then(function (data) {
$scope.claims = data.data;
});
.then(function (data) {
$scope.claims = data.data;
});
}
// Create a user, do some validation too
// Create a user, do some validation too
$scope.addUser = function () {
if (!$scope.user.username || !$scope.user.password) {
@ -50,23 +51,35 @@
return;
}
userManagementService.addUser($scope.user, $scope.selectedClaims).then(function (data) {
if (data.message) {
$scope.error.error = true;
$scope.error.errorMessage = data.message;
} else {
$scope.users.push(data); // Push the new user into the array to update the DOM
$scope.user = {};
$scope.selectedClaims = {};
}
});
userManagementService.addUser($scope.user, $scope.selectedClaims)
.then(function (data) {
if (data.message) {
$scope.error.error = true;
$scope.error.errorMessage = data.message;
} else {
$scope.users.push(data); // Push the new user into the array to update the DOM
$scope.user = {};
$scope.selectedClaims = {};
}
});
};
$scope.$watch('claims|filter:{selected:true}', function (nv) {
$scope.selectedClaims = nv.map(function (claim) {
return claim.name;
});
}, true);
$scope.$watch('claims|filter:{selected:true}',
function (nv) {
$scope.selectedClaims = nv.map(function (claim) {
return claim.name;
});
},
true);
$scope.updateUser = function () {
}
function getBaseUrl() {
return $('#baseUrl').val();
}
// On page load

@ -5,6 +5,21 @@
return opts.inverse(this);
});
Function.prototype.bind = function (parent) {
var f = this;
var args = [];
for (var a = 1; a < arguments.length; a++) {
args[args.length] = arguments[a];
}
var temp = function () {
return f.apply(parent, args);
}
return (temp);
}
$(function () {

@ -8,21 +8,6 @@
return s;
}
Function.prototype.bind = function (parent) {
var f = this;
var args = [];
for (var a = 1; a < arguments.length; a++) {
args[args.length] = arguments[a];
}
var temp = function () {
return f.apply(parent, args);
}
return (temp);
}
$(function() {
$('[data-toggle="tooltip"]').tooltip();
});

@ -207,6 +207,20 @@ namespace PlexRequests.UI.Helpers
return helper.Raw(asset);
}
public static IHtmlString LoadUserManagementAssets(this HtmlHelpers helper)
{
var assetLocation = GetBaseUrl();
var content = GetContentUrl(assetLocation);
var controller = $"<script src=\"{content}/Content/app/userManagement/userManagementController.js?v={Assembly}\" type=\"text/javascript\"></script>";
controller += $"<script src=\"{content}/Content/app/userManagement/userManagementService.js?v={Assembly}\" type=\"text/javascript\"></script>";
return helper.Raw(controller);
}
public static IHtmlString LoadTableAssets(this HtmlHelpers helper)
{
var sb = new StringBuilder();

@ -16,6 +16,7 @@ namespace PlexRequests.UI.Models
public UserType Type { get; set; }
public string EmailAddress { get; set; }
public UserManagementPlexInformation PlexInfo { get; set; }
public string[] ClaimsArray { get; set; }
}
public class UserManagementPlexInformation

@ -67,7 +67,8 @@ namespace PlexRequests.UI.Modules
ISonarrApi sonarrApi,
ISickRageApi sickRageApi,
ICacheProvider cache,
IAnalytics an) : base("requests", prSettings)
IAnalytics an,
INotificationEngine engine) : base("requests", prSettings)
{
Service = service;
PrSettings = prSettings;
@ -81,6 +82,7 @@ namespace PlexRequests.UI.Modules
CpApi = cpApi;
Cache = cache;
Analytics = an;
NotificationEngine = engine;
Get["/", true] = async (x, ct) => await LoadRequests();
Get["/movies", true] = async (x, ct) => await GetMovies();
@ -108,6 +110,7 @@ namespace PlexRequests.UI.Modules
private ISickRageApi SickRageApi { get; }
private ICouchPotatoApi CpApi { get; }
private ICacheProvider Cache { get; }
private INotificationEngine NotificationEngine { get; }
private async Task<Negotiator> LoadRequests()
{
@ -376,6 +379,8 @@ namespace PlexRequests.UI.Modules
originalRequest.Available = available;
var result = await Service.UpdateRequestAsync(originalRequest);
var plexService = await PlexSettings.GetSettingsAsync();
await NotificationEngine.NotifyUsers(originalRequest, plexService.PlexAuthToken);
return Response.AsJson(result
? new { Result = true, Available = available, Message = string.Empty }
: new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" });

@ -63,7 +63,8 @@ namespace PlexRequests.UI.Modules
Claims = claimsString,
Username = user.UserName,
Type = UserType.LocalUser,
EmailAddress = userProps.EmailAddress
EmailAddress = userProps.EmailAddress,
ClaimsArray = claims
});
}

@ -50,6 +50,7 @@ namespace PlexRequests.UI.NinjectModules
Bind<ICustomUserMapper>().To<UserMapper>();
Bind<INotificationService>().To<NotificationService>().InSingletonScope();
Bind<INotificationEngine>().To<NotificationEngine>();
}
}
}

@ -1,8 +1,7 @@
@using PlexRequests.UI.Helpers
@inherits PlexRequests.UI.Helpers.AngularViewBase
<script src="~/Content/app/userManagement/userManagementController.js"></script>
<script src="~/Content/app/userManagement/userManagementService.js"></script>
@Html.LoadUserManagementAssets()
<div ng-controller="userManagementController" ng-init="init()">
<br />
@ -110,9 +109,27 @@
<div>
<strong>User Type: </strong><span ng-bind="selectedUser.type === 1 ? 'Local User' : 'Plex User'"></span>
</div>
</div>
<br/>
<br/>
<div ng-show="selectedUser.type === 1">
<!--Edit-->
<strong>Modify Roles:</strong>
<!--Load all claims-->
<div class="checkbox" ng-repeat="claim in claims">
<input id="claimCheckboxEdit_{{$id}}" class="checkbox-custom" name="selectedClaims[]" ng-checked="@*//TODO: Need to figure our how to preselect them*@" ng-model="claim.selected" type="checkbox" value="claim" />
<label for="claimCheckboxEdit_{{$id}}">{{claim.name}}</label>
</div>
<button ng-click="updateUser()" class="btn btn-primary-outline">Update</button>
</div>
</div> <!-- End of user side menu -->
</div>
Loading…
Cancel
Save