mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-14 02:26:55 -07:00
Added the ability to invite Plex Friends from the user management screen.
This commit is contained in:
parent
9c10e98a23
commit
505929737c
11 changed files with 138 additions and 25 deletions
|
@ -11,6 +11,7 @@ namespace Ombi.Api.Plex
|
|||
public interface IPlexApi
|
||||
{
|
||||
Task<PlexStatus> GetStatus(string authToken, string uri);
|
||||
Task<PlexLibrariesForMachineId> GetLibrariesForMachineId(string authToken, string machineId);
|
||||
Task<PlexAuthentication> SignIn(UserRequest user);
|
||||
Task<PlexServer> GetServer(string authToken);
|
||||
Task<PlexContainer> GetLibrarySections(string authToken, string plexFullHost);
|
||||
|
|
66
src/Ombi.Api.Plex/Models/PlexLibrariesForMachineId.cs
Normal file
66
src/Ombi.Api.Plex/Models/PlexLibrariesForMachineId.cs
Normal file
|
@ -0,0 +1,66 @@
|
|||
namespace Ombi.Api.Plex.Models
|
||||
{
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[XmlRoot(ElementName = "Section")]
|
||||
public class SectionLite
|
||||
{
|
||||
[XmlAttribute(AttributeName = "id")]
|
||||
public string Id { get; set; }
|
||||
[XmlAttribute(AttributeName = "key")]
|
||||
public string Key { get; set; }
|
||||
[XmlAttribute(AttributeName = "type")]
|
||||
public string Type { get; set; }
|
||||
[XmlAttribute(AttributeName = "title")]
|
||||
public string Title { get; set; }
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Server")]
|
||||
public class ServerLib
|
||||
{
|
||||
[XmlElement(ElementName = "Section")]
|
||||
public List<SectionLite> Section { get; set; }
|
||||
[XmlAttribute(AttributeName = "name")]
|
||||
public string Name { get; set; }
|
||||
[XmlAttribute(AttributeName = "address")]
|
||||
public string Address { get; set; }
|
||||
[XmlAttribute(AttributeName = "port")]
|
||||
public string Port { get; set; }
|
||||
[XmlAttribute(AttributeName = "version")]
|
||||
public string Version { get; set; }
|
||||
[XmlAttribute(AttributeName = "scheme")]
|
||||
public string Scheme { get; set; }
|
||||
[XmlAttribute(AttributeName = "host")]
|
||||
public string Host { get; set; }
|
||||
[XmlAttribute(AttributeName = "localAddresses")]
|
||||
public string LocalAddresses { get; set; }
|
||||
[XmlAttribute(AttributeName = "machineIdentifier")]
|
||||
public string MachineIdentifier { get; set; }
|
||||
[XmlAttribute(AttributeName = "createdAt")]
|
||||
public string CreatedAt { get; set; }
|
||||
[XmlAttribute(AttributeName = "updatedAt")]
|
||||
public string UpdatedAt { get; set; }
|
||||
[XmlAttribute(AttributeName = "owned")]
|
||||
public string Owned { get; set; }
|
||||
[XmlAttribute(AttributeName = "synced")]
|
||||
public string Synced { get; set; }
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "MediaContainer")]
|
||||
public class PlexLibrariesForMachineId
|
||||
{
|
||||
[XmlElement(ElementName = "Server")]
|
||||
public ServerLib Server { get; set; }
|
||||
[XmlAttribute(AttributeName = "friendlyName")]
|
||||
public string FriendlyName { get; set; }
|
||||
[XmlAttribute(AttributeName = "identifier")]
|
||||
public string Identifier { get; set; }
|
||||
[XmlAttribute(AttributeName = "machineIdentifier")]
|
||||
public string MachineIdentifier { get; set; }
|
||||
[XmlAttribute(AttributeName = "size")]
|
||||
public string Size { get; set; }
|
||||
}
|
||||
}
|
|
@ -127,6 +127,13 @@ namespace Ombi.Api.Plex
|
|||
return await Api.Request<PlexContainer>(request);
|
||||
}
|
||||
|
||||
public async Task<PlexLibrariesForMachineId> GetLibrariesForMachineId(string authToken, string machineId)
|
||||
{
|
||||
var request = new Request("", $"https://plex.tv/api/servers/{machineId}", HttpMethod.Get, ContentType.Xml);
|
||||
await AddHeaders(request, authToken);
|
||||
return await Api.Request<PlexLibrariesForMachineId>(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
// 192.168.1.69:32400/library/metadata/3662/allLeaves
|
||||
// The metadata ratingkey should be in the Cache
|
||||
|
|
|
@ -34,6 +34,19 @@ export interface IPlexLibResponse {
|
|||
data: IPlexLibraries;
|
||||
}
|
||||
|
||||
export interface IPlexLibSimpleResponse {
|
||||
successful: boolean;
|
||||
message: string;
|
||||
data: IPlexSection[];
|
||||
}
|
||||
|
||||
export interface IPlexSection {
|
||||
id: string;
|
||||
key: string;
|
||||
type: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface IMediaContainer {
|
||||
directory: IDirectory[];
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Observable } from "rxjs";
|
|||
|
||||
import { ServiceHelpers } from "../service.helpers";
|
||||
|
||||
import { IPlexAuthentication, IPlexLibResponse, IPlexOAuthViewModel, IPlexServer, IPlexServerAddViewModel, IPlexServerViewModel, IPlexUserAddResponse, IPlexUserViewModel, IUsersModel } from "../../interfaces";
|
||||
import { IPlexAuthentication, IPlexLibResponse, IPlexLibSimpleResponse, IPlexOAuthViewModel, IPlexServer, IPlexServerAddViewModel, IPlexServerViewModel, IPlexUserAddResponse, IPlexUserViewModel, IUsersModel } from "../../interfaces";
|
||||
|
||||
@Injectable()
|
||||
export class PlexService extends ServiceHelpers {
|
||||
|
@ -30,8 +30,8 @@ export class PlexService extends ServiceHelpers {
|
|||
return this.http.post<IPlexLibResponse>(`${this.url}Libraries`, JSON.stringify(plexSettings), {headers: this.headers});
|
||||
}
|
||||
|
||||
public getLibrariesFromSettings(machineId: string): Observable<IPlexLibResponse> {
|
||||
return this.http.get<IPlexLibResponse>(`${this.url}Libraries/${machineId}`, {headers: this.headers});
|
||||
public getLibrariesFromSettings(machineId: string): Observable<IPlexLibSimpleResponse> {
|
||||
return this.http.get<IPlexLibSimpleResponse>(`${this.url}Libraries/${machineId}`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public addUserToServer(user: IPlexUserViewModel): Observable<IPlexUserAddResponse> {
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<p>You can invite a user to share your Plex Library here. The invited user will be asked to confirm friendship.</p>
|
||||
<p>Please note that this user will not appear in your Ombi Users since they have not accepted the Plex Invite, as soon as they accept
|
||||
the Plex invite then the User Importer job will run (if enabled) and add the user into Ombi.
|
||||
</p>
|
||||
|
||||
|
||||
<div *ngIf="plexServers">
|
||||
|
@ -39,21 +42,25 @@
|
|||
|
||||
|
||||
<div *ngIf="!form.value.allLibsSelected">
|
||||
<div *ngFor="let lib of plexLibs.mediaContainer.directory">
|
||||
<div class="form-group">
|
||||
<div *ngFor="let lib of plexLibs">
|
||||
<div class="col-md-4">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="{{lib.key}}" value={{lib.key}} (change)="checkedLib($event.target.checked, $event.target.value)">
|
||||
<label for="{{lib.key}}">{{lib.title}}</label>
|
||||
<input type="checkbox" id="{{lib.id}}" value={{lib.id}} (change)="checkedLib($event.target.checked, $event.target.value)">
|
||||
<label for="{{lib.id}}">{{lib.title}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary-outline" (click)="onSubmit(form)" [disabled]="form.invalid">Add</button>
|
||||
<button type="button" class="btn btn-primary-outline" (click)="onSubmit(form)" [disabled]="form.invalid">Add</button>
|
||||
<button type="button" class="btn btn-danger-outline" (click)="activeModal.close('Close click')">Close</button>
|
||||
</div>
|
|
@ -4,7 +4,7 @@ import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
|||
|
||||
import { NotificationService, PlexService } from "../services";
|
||||
|
||||
import { IPlexLibraries, IPlexServersAdd } from "../interfaces";
|
||||
import { IPlexSection, IPlexServersAdd } from "../interfaces";
|
||||
|
||||
@Component({
|
||||
selector: "ngbd-modal-content",
|
||||
|
@ -15,7 +15,7 @@ export class AddPlexUserComponent implements OnInit {
|
|||
@Input() public name: string;
|
||||
|
||||
public plexServers: IPlexServersAdd[];
|
||||
public plexLibs: IPlexLibraries;
|
||||
public plexLibs: IPlexSection[];
|
||||
|
||||
public libsSelected: number[] = [];
|
||||
|
||||
|
@ -65,12 +65,11 @@ export class AddPlexUserComponent implements OnInit {
|
|||
}
|
||||
|
||||
public onSubmit(form: FormGroup) {
|
||||
debugger;
|
||||
if (form.invalid) {
|
||||
this.notificationService.error("Please check your entered values");
|
||||
return;
|
||||
}
|
||||
const libs = form.value.allLibsSelected ? this.plexLibs.mediaContainer.directory.map(x => +x.key) : this.libsSelected;
|
||||
const libs = form.value.allLibsSelected ? [] : this.libsSelected;
|
||||
|
||||
this.plexService.addUserToServer({ username: form.value.username, machineIdentifier: form.value.selectedServer, libsSelected: libs }).subscribe(x => {
|
||||
if (x.success) {
|
||||
|
@ -78,6 +77,7 @@ export class AddPlexUserComponent implements OnInit {
|
|||
} else {
|
||||
this.notificationService.error(x.error);
|
||||
}
|
||||
this.activeModal.close();
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<h1>User Management</h1>
|
||||
|
||||
|
||||
<div *ngIf="plexEnabled">
|
||||
<button type="button" style="float:right;" class="btn btn-success-outline" (click)="open()">Add Plex Friend</button>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-success-outline" [routerLink]="['/usermanagement/add']">Add User To Ombi</button>
|
||||
|
||||
<button type="button" style="float:right;" class="btn btn-primary-outline"(click)="showBulkEdit = !showBulkEdit" [disabled]="!hasChecked()">Bulk Edit</button>
|
||||
<div *ngIf="plexEnabled">
|
||||
<button type="button" style="float:right;" class="btn btn-success-outline" (click)="open()">Add Plex Friend</button>
|
||||
</div>
|
||||
<!-- Table -->
|
||||
<table class="table table-striped table-hover table-responsive table-condensed table-usermanagement">
|
||||
<thead>
|
||||
|
|
|
@ -977,7 +977,17 @@ a > h4:hover {
|
|||
top: 7%;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
background-color: #282828;
|
||||
padding-top:75px;
|
||||
.modal.fade .modal-dialog {
|
||||
-webkit-transform: translate(0, 0%);
|
||||
-ms-transform: translate(0, 0%);
|
||||
-o-transform: translate(0, 0%);
|
||||
transform: translate(0, 0%);
|
||||
-webkit-transition: -webkit-transform .3s ease-out;
|
||||
-o-transition: -o-transform .3s ease-out;
|
||||
transition: transform .3s ease-out;
|
||||
}
|
||||
|
||||
.modal-footer .btn+.btn {
|
||||
margin-left: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
10
src/Ombi/Controllers/External/PlexController.cs
vendored
10
src/Ombi/Controllers/External/PlexController.cs
vendored
|
@ -130,18 +130,18 @@ namespace Ombi.Controllers.External
|
|||
|
||||
[HttpGet("Libraries/{machineId}")]
|
||||
[PowerUser]
|
||||
public async Task<PlexLibrariesResponse> GetPlexLibraries(string machineId)
|
||||
public async Task<PlexLibrariesLiteResponse> GetPlexLibraries(string machineId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var s = await PlexSettings.GetSettingsAsync();
|
||||
var settings = s.Servers.FirstOrDefault(x => x.MachineIdentifier == machineId);
|
||||
var libs = await PlexApi.GetLibrarySections(settings.PlexAuthToken, settings.FullUri);
|
||||
var libs = await PlexApi.GetLibrariesForMachineId(settings.PlexAuthToken, machineId);
|
||||
|
||||
return new PlexLibrariesResponse
|
||||
return new PlexLibrariesLiteResponse
|
||||
{
|
||||
Successful = true,
|
||||
Data = libs
|
||||
Data = libs.Server.Section
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -149,7 +149,7 @@ namespace Ombi.Controllers.External
|
|||
_log.LogWarning(e, "Error thrown when attempting to obtain the plex libs");
|
||||
|
||||
var message = e.InnerException != null ? $"{e.Message} - {e.InnerException.Message}" : e.Message;
|
||||
return new PlexLibrariesResponse
|
||||
return new PlexLibrariesLiteResponse
|
||||
{
|
||||
Successful = false,
|
||||
Message = message
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
// ************************************************************************/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Ombi.Api.Plex.Models;
|
||||
|
||||
namespace Ombi.Models.External
|
||||
|
@ -35,4 +36,11 @@ namespace Ombi.Models.External
|
|||
public bool Successful { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
public class PlexLibrariesLiteResponse
|
||||
{
|
||||
public List<SectionLite> Data { get; set; }
|
||||
public bool Successful { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue