Fixed the about page, we now include a count of the users online too!

pull/3895/head
Jamie Rees 6 years ago
parent 08a1bd53c5
commit 93722bb546

@ -51,15 +51,13 @@ namespace Ombi.Schedule.Jobs.Plex
public class PlexContentSync : IPlexContentSync public class PlexContentSync : IPlexContentSync
{ {
public PlexContentSync(ISettingsService<PlexSettings> plex, IPlexApi plexApi, ILogger<PlexContentSync> logger, IPlexContentRepository repo, public PlexContentSync(ISettingsService<PlexSettings> plex, IPlexApi plexApi, ILogger<PlexContentSync> logger, IPlexContentRepository repo,
IPlexEpisodeSync epsiodeSync, IRefreshMetadata metadataRefresh, IPlexAvailabilityChecker checker, IHubContext<NotificationHub> hub) IPlexEpisodeSync epsiodeSync, IHubContext<NotificationHub> hub)
{ {
Plex = plex; Plex = plex;
PlexApi = plexApi; PlexApi = plexApi;
Logger = logger; Logger = logger;
Repo = repo; Repo = repo;
EpisodeSync = epsiodeSync; EpisodeSync = epsiodeSync;
Metadata = metadataRefresh;
Checker = checker;
Notification = hub; Notification = hub;
Plex.ClearCache(); Plex.ClearCache();
} }
@ -69,8 +67,6 @@ namespace Ombi.Schedule.Jobs.Plex
private ILogger<PlexContentSync> Logger { get; } private ILogger<PlexContentSync> Logger { get; }
private IPlexContentRepository Repo { get; } private IPlexContentRepository Repo { get; }
private IPlexEpisodeSync EpisodeSync { get; } private IPlexEpisodeSync EpisodeSync { get; }
private IRefreshMetadata Metadata { get; }
private IPlexAvailabilityChecker Checker { get; }
private IHubContext<NotificationHub> Notification { get; set; } private IHubContext<NotificationHub> Notification { get; set; }
public async Task Execute(IJobExecutionContext context) public async Task Execute(IJobExecutionContext context)

@ -0,0 +1,7 @@
import { UserType } from "./IUser";
export interface IConnectedUser {
userId: string;
displayName: string;
userType: UserType
}

@ -18,3 +18,4 @@ export * from "./ILidarr";
export * from "./ISearchMusicResult"; export * from "./ISearchMusicResult";
export * from "./IVote"; export * from "./IVote";
export * from "./IFailedRequests"; export * from "./IFailedRequests";
export * from "./IHub";

@ -0,0 +1,19 @@
import { APP_BASE_HREF } from "@angular/common";
import { Injectable, Inject } from "@angular/core";
import { Observable } from "rxjs";
import { HttpClient } from "@angular/common/http";
import { IConnectedUser } from "../interfaces";
import { ServiceHelpers } from "./service.helpers";
@Injectable()
export class HubService extends ServiceHelpers {
constructor(public http: HttpClient, @Inject(APP_BASE_HREF) href:string) {
super(http, "/api/v2/hub/", href);
}
public getConnectedUsers(): Promise<IConnectedUser[]> {
return this.http.get<IConnectedUser[]>(`${this.url}users`, {headers: this.headers}).toPromise();
}
}

@ -19,3 +19,4 @@ export * from "./requestretry.service";
export * from "./searchV2.service"; export * from "./searchV2.service";
export * from "./custompage.service"; export * from "./custompage.service";
export * from "./message.service"; export * from "./message.service";
export * from "./hub.service";

@ -1,106 +1,71 @@
 <settings-menu></settings-menu>
<settings-menu></settings-menu>
<div *ngIf="about" class="container"> <div *ngIf="about" class="container">
<fieldset>
<legend>About</legend> <legend>About</legend>
<form>
<div class="col-md-8">
<table class="table table-striped table-hover table-responsive table-condensed">
<thead>
</thead>
<tbody>
<tr>
<td>
<span>Version</span>
</td>
<td>
<span>{{about.version}} <a [routerLink]="['/Settings/Update']" *ngIf="newUpdate" style="color:#df691a"><b>(New Update Available)</b></a></span>
</td>
</tr>
<tr>
<td>
<span>Branch</span>
</td>
<td>
<span>{{about.branch}}</span>
</td>
</tr>
<tr>
<td>
<span>Github</span>
</td>
<td>
<a href="https://github.com/tidusjar/Ombi" target="_blank">https://github.com/tidusjar/Ombi</a>
</td>
</tr>
<tr>
<td>
<span>Discord</span>
</td>
<td>
<a href="https://discord.gg/Sa7wNWb" target="_blank">https://discord.gg/Sa7wNWb</a>
</td>
</tr>
<tr> <div class="mat-table">
<td> <div class="mat-row" *ngIf="connectedUsers">
<span>Reddit</span> <div class="mat-cell">Users Online</div>
</td> <div class="mat-cell">{{connectedUsers.length}}</div>
<td> </div>
<a href="https://www.reddit.com/r/Ombi/" target="_blank">https://www.reddit.com/r/Ombi/</a> <div class="mat-row">
</td> <div class="mat-cell">Version</div>
</tr> <div class="mat-cell">{{about.version}} <a [routerLink]="['/Settings/Update']" *ngIf="newUpdate"
<tr> style="color:#df691a"><b>(New Update Available)</b></a></div>
<td> </div>
<span>Issues</span>
</td> <div class="mat-row">
<td> <div class="mat-cell">Branch</div>
<a href="https://github.com/tidusjar/Ombi/issues" target="_blank">https://github.com/tidusjar/Ombi/issues</a> <div class="mat-cell">{{about.branch}}</div>
</td> </div>
</tr>
<tr> <div class="mat-row">
<td> <div class="mat-cell">Github</div>
<span>Wiki</span> <div class="mat-cell"> <a href="https://github.com/tidusjar/Ombi"
</td> target="_blank">https://github.com/tidusjar/Ombi</a></div>
<td> </div>
<a href="https://github.com/tidusjar/Ombi/wiki" target="_blank">https://github.com/tidusjar/Ombi/wiki</a>
</td> <div class="mat-row">
</tr> <div class="mat-cell">Discord</div>
<tr> <div class="mat-cell"><a href="https://discord.gg/Sa7wNWb" target="_blank">https://discord.gg/Sa7wNWb</a></div>
<td> </div>
<span>OS Architecture</span>
</td> <div class="mat-row">
<td> <div class="mat-cell">Reddit</div>
<span>{{about.osArchitecture}}</span> <div class="mat-cell"> <a href="https://www.reddit.com/r/Ombi/" target="_blank">https://www.reddit.com/r/Ombi/</a>
</td> </div>
</tr> </div>
<tr>
<td> <div class="mat-row">
<span>OS Description</span> <div class="mat-cell">Issues</div>
</td> <div class="mat-cell"> <a href="https://github.com/tidusjar/Ombi/issues"
<td> target="_blank">https://github.com/tidusjar/Ombi/issues</a></div>
<span>{{about.osDescription}}</span> </div>
</td>
</tr> <div class="mat-row">
<tr> <div class="mat-cell">Wiki</div>
<td> <div class="mat-cell"> <a href="https://github.com/tidusjar/Ombi/wiki"
<span>Process Architecture</span> target="_blank">https://github.com/tidusjar/Ombi/wiki</a></div>
</td> </div>
<td>
<span>{{about.processArchitecture}}</span> <div class="mat-row">
</td> <div class="mat-cell">OS Architecture</div>
</tr> <div class="mat-cell"> {{about.osArchitecture}}</div>
<tr> </div>
<td>
<span>Application Base Path</span> <div class="mat-row">
</td> <div class="mat-cell">OS Description</div>
<td> <div class="mat-cell">{{about.osDescription}}</div>
<span>{{about.applicationBasePath}}</span> </div>
</td>
</tr> <div class="mat-row">
</tbody> <div class="mat-cell">Process Architecture</div>
</table> <div class="mat-cell">{{about.processArchitecture}}</div>
</div>
<div class="mat-row">
<div class="mat-cell">Application Base Path</div>
<div class="mat-cell">{{about.applicationBasePath}}</div>
</div>
</div> </div>
</form>
</fieldset>
</div> </div>

@ -0,0 +1,20 @@
.mat-table {
display: block;
}
.mat-row,
.mat-header-row {
display: flex;
border-bottom-width: 1px;
border-bottom-style: solid;
align-items: center;
min-height: 48px;
padding: 0 24px;
}
.mat-cell,
.mat-header-cell {
flex: 1;
overflow: hidden;
word-wrap: break-word;
}

@ -1,19 +1,23 @@
import { Component, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { IAbout } from "../../interfaces/ISettings"; import { IAbout } from "../../interfaces/ISettings";
import { JobService, SettingsService } from "../../services"; import { JobService, SettingsService, HubService } from "../../services";
import { IConnectedUser } from "../../interfaces";
@Component({ @Component({
templateUrl: "./about.component.html", templateUrl: "./about.component.html",
styleUrls: ["./about.component.scss"]
}) })
export class AboutComponent implements OnInit { export class AboutComponent implements OnInit {
public about: IAbout; public about: IAbout;
public newUpdate: boolean; public newUpdate: boolean;
public connectedUsers: IConnectedUser[];
constructor(private readonly settingsService: SettingsService, constructor(private readonly settingsService: SettingsService,
private readonly jobService: JobService) { } private readonly jobService: JobService,
private readonly hubService: HubService) { }
public ngOnInit() { public async ngOnInit() {
this.settingsService.about().subscribe(x => this.about = x); this.settingsService.about().subscribe(x => this.about = x);
this.jobService.getCachedUpdate().subscribe(x => { this.jobService.getCachedUpdate().subscribe(x => {
if (x === true) { if (x === true) {
@ -21,5 +25,6 @@ export class AboutComponent implements OnInit {
} }
}); });
this.connectedUsers = await this.hubService.getConnectedUsers();
} }
} }

@ -51,6 +51,7 @@ import { SettingsMenuComponent } from "./settingsmenu.component";
import { AutoCompleteModule, CalendarModule, DialogModule, InputSwitchModule, InputTextModule, MenuModule, RadioButtonModule, TooltipModule } from "primeng/primeng"; import { AutoCompleteModule, CalendarModule, DialogModule, InputSwitchModule, InputTextModule, MenuModule, RadioButtonModule, TooltipModule } from "primeng/primeng";
import { MatMenuModule} from "@angular/material"; import { MatMenuModule} from "@angular/material";
import { SharedModule } from "../shared/shared.module"; import { SharedModule } from "../shared/shared.module";
import { HubService } from "../services/hub.service";
const routes: Routes = [ const routes: Routes = [
{ path: "Ombi", component: OmbiComponent, canActivate: [AuthGuard] }, { path: "Ombi", component: OmbiComponent, canActivate: [AuthGuard] },
@ -160,6 +161,7 @@ const routes: Routes = [
NotificationMessageService, NotificationMessageService,
LidarrService, LidarrService,
RequestRetryService, RequestRetryService,
HubService,
], ],
}) })

@ -1,53 +1,56 @@
using System.Threading.Tasks; using System;
using Microsoft.AspNetCore.Authorization; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Ombi.Api.TheMovieDb.Models;
using Ombi.Core.Engine.V2;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Ombi.Core; using Microsoft.EntityFrameworkCore;
using Ombi.Core.Engine.Interfaces; using Ombi.Attributes;
using Ombi.Core.Models.Search; using Ombi.Core.Authentication;
using Ombi.Core.Models.Search.V2;
using Ombi.Helpers;
using Ombi.Hubs; using Ombi.Hubs;
using Ombi.Models; using Ombi.Models;
namespace Ombi.Controllers.V2 namespace Ombi.Controllers.V2
{ {
[ApiV2] [ApiV2]
[Authorize] [Admin]
[ApiController] [ApiController]
public class HubController : ControllerBase public class HubController : ControllerBase
{ {
public HubController(IHubContext<NotificationHub> hub) public HubController(OmbiUserManager um)
{ {
_hub = hub; _um = um;
} }
private readonly IHubContext<NotificationHub> _hub; private readonly OmbiUserManager _um;
/// <summary> /// <summary>
/// Returns search results for both TV and Movies /// Returns the currently connected users in Ombi
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet("{searchTerm}")] [HttpGet("Users")]
public async Task MultiSearch(string searchTerm) public async Task<List<ConnectedUsersViewModel>> GetConnectedUsers()
{ {
await _hub.Clients.All.SendAsync("Notification", searchTerm); var users = NotificationHub.UsersOnline.Values;
var allUsers = _um.Users;
var model = new List<ConnectedUsersViewModel>();
foreach (var user in users)
{
var ombiUser = await allUsers.FirstOrDefaultAsync(x => x.Id.Equals(user.UserId, StringComparison.InvariantCultureIgnoreCase));
if (ombiUser == null)
{
continue;
} }
/// <summary> model.Add(new ConnectedUsersViewModel
/// Returns search results for both TV and Movies
/// </summary>
/// <returns></returns>
[HttpGet("admin/{searchTerm}")]
public async Task Admin(string searchTerm)
{ {
var admins = NotificationHub.UsersOnline.Where(x => x.Value.Roles.Contains(OmbiRoles.Admin)).Select(x => x.Key).ToList(); UserId = ombiUser.Id,
await _hub.Clients.Clients(admins).SendAsync("Notification", searchTerm); DisplayName = ombiUser.UserAlias,
UserType = ombiUser.UserType
});
}
return model;
} }
} }
} }

@ -0,0 +1,12 @@

using Ombi.Store.Entities;
namespace Ombi.Models
{
public class ConnectedUsersViewModel
{
public string UserId { get; set; }
public string DisplayName { get; set; }
public UserType UserType { get; set; }
}
}
Loading…
Cancel
Save