pull/1389/head
Jamie.Rees 8 years ago
parent a284db90de
commit 20f493e4cb

@ -11,5 +11,9 @@ namespace Ombi.Core.Engine
Task<RequestEngineResult> RequestMovie(SearchMovieViewModel model);
bool ShouldAutoApprove(RequestType requestType);
Task<IEnumerable<RequestViewModel>> GetRequests();
Task<IEnumerable<RequestViewModel>> GetRequests(int count, int position);
Task<IEnumerable<RequestViewModel>> SearchRequest(string search);
Task RemoveRequest(int requestId);
Task<RequestViewModel> UpdateRequest(RequestViewModel request);
}
}

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Ombi.Core.Models.Requests;
@ -7,6 +8,7 @@ using Ombi.Core.Models.Search;
using Ombi.Core.Requests.Models;
using Ombi.Store.Entities;
using Ombi.TheMovieDbApi;
using Ombi.Helpers;
namespace Ombi.Core.Engine
{
@ -233,7 +235,41 @@ namespace Ombi.Core.Engine
public async Task<IEnumerable<RequestViewModel>> GetRequests()
{
var allRequests = await RequestService.GetAllAsync();
var viewModel = allRequests.Select(movie => new RequestViewModel
var viewModel = MapToVm(allRequests);
return viewModel;
}
public async Task<IEnumerable<RequestViewModel>> GetRequests(int count, int position)
{
var allRequests = await RequestService.GetAllAsync(count, position);
var viewModel = MapToVm(allRequests);
return viewModel;
}
public async Task<IEnumerable<RequestViewModel>> SearchRequest(string search)
{
var allRequests = await RequestService.GetAllAsync();
var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase));
var viewModel = MapToVm(results);
return viewModel;
}
public async Task<RequestViewModel> UpdateRequest(RequestViewModel request)
{
var allRequests = await RequestService.GetAllAsync();
var results = allRequests.FirstOrDefault(x => x.Id == request.Id);
var model = RequestService.UpdateRequest(results);
return MapToVm(new List<RequestModel>{model}).FirstOrDefault();
}
public async Task RemoveRequest(int requestId)
{
await RequestService.DeleteRequestAsync(requestId);
}
private IEnumerable<RequestViewModel> MapToVm(IEnumerable<RequestModel> model)
{
return model.Select(movie => new RequestViewModel
{
ProviderId = movie.ProviderId,
Type = movie.Type,
@ -259,8 +295,6 @@ namespace Ombi.Core.Engine
//RootFolders = rootFolders.ToArray(),
//CurrentRootPath = radarr.Enabled ? GetRootPath(movie.RootFolderSelected, radarr).Result : null
}).ToList();
return viewModel;
}
}
}

@ -16,11 +16,13 @@ namespace Ombi.Core.Requests.Models
Task<RequestModel> CheckRequestAsync(int providerId);
Task<RequestModel> CheckRequestAsync(string musicId);
void DeleteRequest(RequestModel request);
Task DeleteRequestAsync(int request);
Task DeleteRequestAsync(RequestModel request);
RequestModel Get(int id);
IEnumerable<RequestModel> GetAll();
Task<IEnumerable<RequestModel>> GetAllAsync();
Task<IEnumerable<RequestModel>> GetAllAsync(int count, int position);
Task<RequestModel> GetAsync(int id);
RequestBlobs UpdateRequest(RequestModel model);
RequestModel UpdateRequest(RequestModel model);
}
}

@ -92,11 +92,19 @@ namespace Ombi.Core.Models.Requests
var blob = await Repo.GetAsync(request.Id).ConfigureAwait(false);
Repo.Delete(blob);
}
public async Task DeleteRequestAsync(int request)
{
var blob = await Repo.GetAsync(request).ConfigureAwait(false);
Repo.Delete(blob);
}
public RequestBlobs UpdateRequest(RequestModel model)
public RequestModel UpdateRequest(RequestModel model)
{
var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id };
return Repo.Update(entity);
var b = Repo.Get(model.Id);
b.Content = ByteConverterHelper.ReturnBytes(model);
var blob = Repo.Update(b);
return model;
}
public RequestModel Get(int id)
@ -159,6 +167,24 @@ namespace Ombi.Core.Models.Requests
return retVal;
}
public async Task<IEnumerable<RequestModel>> GetAllAsync(int count, int position)
{
var blobs = await Repo.GetAllAsync(count, position).ConfigureAwait(false);
var retVal = new List<RequestModel>();
foreach (var b in blobs)
{
if (b == null)
{
continue;
}
var model = ByteConverterHelper.ReturnObject<RequestModel>(b.Content);
model.Id = b.Id;
retVal.Add(model);
}
return retVal;
}
public void BatchUpdate(IEnumerable<RequestModel> model)
{
var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList();

@ -0,0 +1,12 @@
using System.Globalization;
namespace Ombi.Helpers
{
public static class StringHelper
{
public static bool Contains(this string paragraph, string word, CompareOptions opts)
{
return CultureInfo.CurrentUICulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
}
}
}

@ -11,6 +11,7 @@ namespace Ombi.Store.Repository
RequestBlobs Get(int id);
IEnumerable<RequestBlobs> GetAll();
Task<IEnumerable<RequestBlobs>> GetAllAsync();
Task<IEnumerable<RequestBlobs>> GetAllAsync(int count, int position);
Task<RequestBlobs> GetAsync(int id);
RequestBlobs Insert(RequestBlobs entity);
Task<RequestBlobs> InsertAsync(RequestBlobs entity);

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
@ -61,6 +62,18 @@ namespace Ombi.Store.Repository
//}, 5);
//return item;
}
public async Task<IEnumerable<RequestBlobs>> GetAllAsync(int count, int position)
{
//var key = "GetAll";
//var item = await Cache.GetOrSetAsync(key, async () =>
//{
var page = await Db.Requests.ToListAsync().ConfigureAwait(false);
return page.Skip(position).Take(count);
//}, 5);
//return item;
}
public RequestBlobs Get(int id)
{
@ -99,9 +112,17 @@ namespace Ombi.Store.Repository
public RequestBlobs Update(RequestBlobs entity)
{
return Db.Requests.Update(entity).Entity;
Db.SaveChanges();
try
{
Db.SaveChanges();
return entity;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

@ -1,7 +1,7 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: BaseApiController.cs
// File: BaseV1ApiController.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
@ -29,8 +29,9 @@ using Microsoft.AspNetCore.Mvc;
namespace Ombi.Controllers
{
[Route("api/[controller]")]
public class BaseApiController : Controller
[Route(ApiBase)]
public class BaseV1ApiController : Controller
{
protected const string ApiBase = "api/v1/[controller]";
}
}

@ -7,7 +7,7 @@ using Ombi.Core.Models.Search;
namespace Ombi.Controllers
{
public class RequestController : BaseApiController
public class RequestController : BaseV1ApiController
{
public RequestController(IRequestEngine engine)
{
@ -22,10 +22,34 @@ namespace Ombi.Controllers
return await RequestEngine.GetRequests();
}
[HttpGet("{count:int}/{position:int}", Name = "GetRequestsByCount")]
public async Task<IEnumerable<RequestViewModel>> GetRequests(int count, int position)
{
return await RequestEngine.GetRequests(count, position);
}
[HttpPost("movie")]
public async Task<RequestEngineResult> SearchMovie([FromBody]SearchMovieViewModel movie)
public async Task<RequestEngineResult> RequestMovie([FromBody]SearchMovieViewModel movie)
{
return await RequestEngine.RequestMovie(movie);
}
[HttpGet("search/{searchTerm}")]
public async Task<IEnumerable<RequestViewModel>> Search(string searchTerm)
{
return await RequestEngine.SearchRequest(searchTerm);
}
[HttpDelete("{requestId:int}")]
public async Task DeleteRequest(int requestId)
{
await RequestEngine.RemoveRequest(requestId);
}
[HttpPost]
public async Task<RequestViewModel> UpdateRequest([FromBody]RequestViewModel model)
{
return await RequestEngine.UpdateRequest(model);
}
}
}

@ -8,7 +8,7 @@ using Ombi.Core.Models.Search;
namespace Ombi.Controllers
{
public class SearchController : BaseApiController
public class SearchController : BaseV1ApiController
{
public SearchController(IMovieEngine movie)
{

@ -41,7 +41,7 @@ namespace Ombi
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
@ -60,7 +60,7 @@ namespace Ombi
});
app.UseMvc(routes =>
{
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");

@ -31,7 +31,7 @@ var paths = {
'@angular/platform-browser-dynamic',
'@angular/http',
'@angular/router',
'@angular/forms'
'@angular/forms',
],
dest: './lib'
},
@ -56,7 +56,7 @@ var paths = {
'./bower_components/PACE/pace.js',
'./node_modules/bootstrap/dist/js/bootstrap.js',
'./node_modules/tether/dist/js/tether.js',
'./systemjs.config.js'
'./systemjs.config.js',
],
dest: './lib/'
},
@ -118,7 +118,12 @@ var paths = {
name: 'primeng',
src: './node_modules/primeng/**/*.js',
dest: './lib/primeng/'
}
},
{
name: "angular2-infinite-scroll",
src: ['./node_modules/angular2-infinite-scroll/**/*.js', '!./node_modules/angular2-infinite-scroll/bundles/**/*.js'],
dest:"./lib/angular2-infinite-scroll/"
},
],
sass: { // Simple sass->css compilation
src: ['./Styles/**/*.scss', '!./Styles/primeng/**'],

@ -16,10 +16,12 @@
"@angular/router": "^4.0.0",
"@types/jquery": "^2.0.33",
"@types/systemjs": "^0.20.2",
"angular2-infinite-scroll": "^0.3.4",
"bootstrap": "3.3.6",
"core-js": "^2.4.1",
"del": "^2.2.2",
"gulp": "~3.9.1",
"gulp-changed": "^1.3.0",
"gulp-changed": "^1.3.0",
"gulp-clean-css": "^3.0.4",
"gulp-filter": "^5.0.0",
"gulp-if": "^2.0.2",
@ -39,7 +41,6 @@
"systemjs-builder": "^0.15.34",
"tether": "^1.4.0",
"typescript": "^2.2.1",
"zone.js": "^0.8.5",
"bootstrap": "3.3.6"
"zone.js": "^0.8.5"
}
}

@ -8,6 +8,8 @@ import { AppComponent } from './app.component';
import { RouterModule, Routes } from '@angular/router';
import { HttpModule } from '@angular/http';
import { InfiniteScrollModule } from 'angular2-infinite-scroll/angular2-infinite-scroll'
import { SearchComponent } from './search/search.component';
import { RequestComponent } from './requests/request.component';
import { PageNotFoundComponent } from './errors/not-found.component';
@ -41,7 +43,8 @@ const routes: Routes = [
FormsModule,
SettingsModule,
DataTableModule,
SharedModule
SharedModule,
InfiniteScrollModule
],
declarations: [
AppComponent,

@ -24,4 +24,9 @@
export enum RequestType {
movie = 1,
tvShow = 2
}
export interface IRequestsPageScroll {
count: number,
position:number
}

@ -1,46 +1,182 @@
<h1 id="searchTitle">Requests</h1>
<input #gb type="text" pInputText size="50" placeholder="Search">
<p-dataTable [value]="requests" expandableRows="true" [rows]="15" [paginator]="true" [pageLinks]="3" [rowsPerPageOptions]="[5,10,20,50]" [globalFilter]="gb">
<p-column expander="true" styleClass="col-icon"></p-column>
<p-column field="title" header="Title" [sortable]="true"></p-column>
<p-column field="requestedDate" header="Requested Date" [sortable]="true"></p-column>
<p-column field="approved" header="Approved" [sortable]="true">
<ng-template let-col let-request="rowData" pTemplate="body">
<span *ngIf="requests[col]" class="fa fa-check"></span>
<span *ngIf="!requests[col]" class="fa fa-times"></span>
</ng-template>
</p-column>
<ng-template let-request pTemplate="rowexpansion">
<div class="ui-grid ui-grid-responsive ui-fluid" style="font-size:16px;padding:20px">
<div class="ui-grid-row">
<div class="ui-grid-col-3" style="text-align:center">
<i class="fa fa-search" (click)="showCar(car)" style="cursor:pointer;float:left;margin-top:40px"></i>
<img src="https://image.tmdb.org/t/p/w150/{{request.posterPath}}">
<img *ngIf="request.type === 2" src="{{request.posterPath}}">
</div>
<div class="ui-grid-col-9">
<div class="ui-grid ui-grid-responsive ui-grid-pad">
<div class="ui-grid-row">
<div class="ui-grid-col-2 label">Type: </div>
<div class="ui-grid-col-10">{{request.type}}</div>
</div>
<div class="ui-grid-row">
<div class="ui-grid-col-2 label">Status: </div>
<div class="ui-grid-col-10">{{request.status}}</div>
</div>
<div class="ui-grid-row">
<div class="ui-grid-col-2 label">Approved: </div>
<div class="ui-grid-col-10">{{request.approved}}</div>
</div>
<div class="ui-grid-row">
<div class="ui-grid-col-2 label">Available: </div>
<div class="ui-grid-col-10">{{request.available}}</div>
</div>
</div>
</div>
</div>
</div>
</ng-template>
</p-dataTable>
<h1 id="searchTitle">Requests</h1>
<div class="form-group">
<div>
<input type="text" class="form-control form-control-custom" placeholder="Search" (keyup)="search($event)">
</div>
</div>
<br/>
<div infinite-scroll
[infiniteScrollDistance]="1"
[infiniteScrollThrottle]="100"
(scrolled)="loadMore()">
<div *ngFor="let request of requests">
<div class="row">
<div class="col-sm-2">
<img *ngIf="request.type == 1" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{request.posterPath}}" alt="poster">
<img *ngIf="request.type == 2" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{request.posterPath}}" alt="poster">
</div>
<div class="col-sm-5 ">
<div>
<a href="http://www.imdb.com/title/{{request.imdb}}/" target="_blank">
<h4 class="request-title">{{request.title}} ({{request.releaseDate | date: yyyy}})</h4>
</a>
</div>
<br />
<div>
<span>Status: </span>
<span class="label label-success">{{request.status}}</span>
</div>
<div>
<span>Request status: </span>
<span *ngIf="request.available" class="label label-success">Request Available</span>
<span *ngIf="request.approved" class="label label-info">Processing Request</span>
<span *ngIf="request.denied" class="label label-danger">Request Denied</span>
<span *ngIf="request.deniedReason" title="{{request.deniedReason}}"><i class="fa fa-info-circle"></i></span>
<span *ngIf="!request.approved && !request.availble" class="label label-warning">Pending Approval</span>
</div>
<div *ngIf="request.denied">
Denied: <i style="color:red;" class="fa fa-check"></i>
</div>
<div>Release Date: {{request.releaseDate}}</div>
<!--{{#if_eq type "tv"}}
{{#if episodes}}
Episodes: <span class="customTooltip" data-tooltip-content="#{{requestId}}toolTipContent"><i class="fa fa-info-circle"></i></span>
{{else}}
<div>@UI.Requests_SeasonsRequested: {{seriesRequested}}</div>
{{/if}}
{{/if_eq}}-->
<div *ngIf="request.requestedUsers">Requested By: {{request.requestedUsers}}</div>
<div>Requested Date: {{request.requestedDate}}</div>
<!--{{#if admin}}
{{#if currentRootPath}}
<div class="{{requestId}}rootPathMain">Root Path: <span id="{{requestId}}currentRootPath">{{currentRootPath}}</span></div>
{{/if}}
{{/if}}
<div>
{{#if_eq issueId 0}}
@*Nothing*@
{{else}}
@UI.Issues_Issue: <a href="@formAction/issues/{{issueId}}"><i class="fa fa-check"></i></a>
{{/if_eq}}
</div>-->
</div>
<div class="col-sm-3 col-sm-push-3">
<div *ngIf="!request.admin">
<div *ngIf="!request.approved">
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
<div *ngIf="request.hasQualities" class="btn-group btn-split">
<button type="button" (click)="approve(request)" class="btn btn-sm btn-success-outline approve"><i class="fa fa-plus"></i> Approve</button>
<button type="button" class="btn btn-success-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<!--<ul class="dropdown-menu">
{{#each qualities}}
<li><a href="#" class="approve-with-quality" id="{{id}}">{{name}}</a></li>
{{/each}}
</ul>-->
</div>
<button *ngIf="!request.hasQualities" (click)="approve(request)" style="text-align: right" class="btn btn-sm btn-success-outline approve" type="submit"><i class="fa fa-plus"></i> Approve</button>
<!--<form method="POST" action="@formAction/requests/changeRootFolder{{#if_eq type "tv"}}tv{{else}}movie{{/if_eq}}" id="changeFolder{{requestId}}">
<input name="requestId" type="text" value="{{requestId}}" hidden="hidden" />
{{#if_eq hasRootFolders true}}
<div class="btn-group btn-split">
<button type="button" class="btn btn-sm btn-success-outline" id="changeRootFolderBtn{{requestId}}" custom-button="{{requestId}}">@*<i class="fa fa-plus"></i>*@ Change Root Folder</button>
<button type="button" class="btn btn-success-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">@UI.Requests_ToggleDropdown</span>
</button>
<ul class="dropdown-menu">
{{#each rootFolders}}
<li><a href="#" class="change-root-folder" id="{{id}}" requestId="{{requestId}}">{{path}}</a></li>
{{/each}}
</ul>
</div>
{{/if_eq}}
</form>-->
<div *ngIf="!request.denied">
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
<input name="reason" type="text" hidden="hidden" />
<div class="btn-group btn-split">
<button type="button" (click)="deny(request)" class="btn btn-sm btn-danger-outline deny"><i class="fa fa-times"></i> Deny</button>
<button type="button" class="btn btn-danger-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">@UI.Requests_ToggleDropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="deny-with-reason" id="denyReason{{request.requestId}}" href="#" data-toggle="modal" data-target="#denyReasonModal">Deny with a reason</a></li>
</ul>
</div>
</div>
</div>
<button (click)="removeRequest(request)" style="text-align: right" class="btn btn-sm btn-danger-outline delete"><i class="fa fa-minus"></i> Remove</button>
<button *ngIf="request.available" (click)="changeAvailability(request, true)" style="text-align: right" value="false" class="btn btn-sm btn-info-outline change"><i class="fa fa-minus"></i> Mark Unavailable</button>
<button *ngIf="!request.available" (click)="changeAvailability(request, false)" style="text-align: right" value="true" class="btn btn-sm btn-success-outline change"><i class="fa fa-plus"></i> Mark Available</button>
</div>
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
<div class="dropdown">
<button id="{{request.requestId}}" class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="fa fa-plus"></i> Report Issue
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a id="{{request.requestId}}" issue-select="0" class="dropdownIssue" href="#">@UI.Issues_WrongAudio</a></li>
<li><a id="{{request.requestId}}" issue-select="1" class="dropdownIssue" href="#">@UI.Issues_NoSubs</a></li>
<li><a id="{{request.requestId}}" issue-select="2" class="dropdownIssue" href="#">@UI.Issues_WrongContent</a></li>
<li><a id="{{request.requestId}}" issue-select="3" class="dropdownIssue" href="#">@UI.Issues_Playback</a></li>
<li><a id="{{request.requestId}}" issue-select="4" class="dropdownIssue" href="#" data-toggle="modal" data-target="#myModal">@UI.Issues_Other</a></li>
</ul>
</div>
</div>
</div>
<hr />
</div>
</div>

@ -1,4 +1,10 @@
import { Component, OnInit } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/map';
@ -14,11 +20,83 @@ import { IRequestModel } from '../interfaces/IRequestModel';
providers: [RequestService]
})
export class RequestComponent implements OnInit {
constructor(private requestService: RequestService) { }
constructor(private requestService: RequestService) {
this.searchChanged
.debounceTime(600) // Wait Xms afterthe last event before emitting last event
.distinctUntilChanged() // only emit if value is different from previous value
.subscribe(x => {
this.searchText = x as string;
if (this.searchText === "") {
this.resetSearch();
return;
}
this.requestService.searchRequests(this.searchText).subscribe(x => this.requests = x);
});
}
requests: IRequestModel[];
searchChanged: Subject<string> = new Subject<string>();
searchText: string;
private currentlyLoaded: number;
private amountToLoad : number;
ngOnInit() {
this.requestService.getAllRequests().subscribe(x => this.requests = x);
this.amountToLoad = 5;
this.currentlyLoaded = 5;
this.loadInit();
}
loadMore() {
this.requestService.getRequests(this.amountToLoad, this.currentlyLoaded + 1).subscribe(x => {
this.requests.push.apply(this.requests, x);
this.currentlyLoaded = this.currentlyLoaded + this.amountToLoad;
});
}
search(text: any) {
this.searchChanged.next(text.target.value);
}
removeRequest(request: IRequestModel) {
this.requestService.removeRequest(request).subscribe();
this.removeRequestFromUi(request);
}
changeAvailability(request: IRequestModel, available: boolean) {
request.available = available;
this.updateRequest(request);
}
approve(request: IRequestModel) {
request.approved = true;
this.updateRequest(request);
}
deny(request: IRequestModel) {
request.approved = false;
request.denied = true;
this.updateRequest(request);
}
private updateRequest(request: IRequestModel) {
this.requestService.updateRequest(request).subscribe(x => request = x);
}
private loadInit() {
this.requestService.getRequests(this.amountToLoad, 0).subscribe(x => this.requests = x);
}
private resetSearch() {
this.currentlyLoaded = 5;
this.loadInit();
}
private removeRequestFromUi(key : IRequestModel) {
var index = this.requests.indexOf(key, 0);
if (index > -1) {
this.requests.splice(index, 1);
}
}
}

@ -8,16 +8,32 @@ import { ISearchMovieResult } from '../interfaces/ISearchMovieResult';
import { IRequestModel } from '../interfaces/IRequestModel';
@Injectable()
export class RequestService {
constructor(private http: Http) {
export class RequestService extends ServiceHelpers {
constructor(http: Http) {
super(http, '/api/v1/Request/');
}
requestMovie(movie: ISearchMovieResult): Observable<IRequestEngineResult> {
return this.http.post('/api/Request/Movie/', JSON.stringify(movie), ServiceHelpers.RequestOptions).map(ServiceHelpers.extractData);
return this.http.post(`${this.url}/Movie/`, JSON.stringify(movie), { headers: this.headers }).map(this.extractData);
}
getAllRequests(): Observable<IRequestModel[]> {
return this.http.get('/api/request').map(ServiceHelpers.extractData);
return this.http.get(this.url).map(this.extractData);
}
getRequests(count: number, position: number): Observable<IRequestModel[]> {
return this.http.get(`${this.url}/${count}/${position}`).map(this.extractData);
}
searchRequests(search: string): Observable<IRequestModel[]> {
return this.http.get(`${this.url}/search/${search}`).map(this.extractData);
}
removeRequest(request: IRequestModel): Observable<void> {
return this.http.delete(`${this.url}/${request.id}`).map(this.extractData);
}
updateRequest(request: IRequestModel) : Observable<IRequestModel> {
return this.http.post(`${this.url}/`, JSON.stringify(request), { headers: this.headers }).map(this.extractData);
}
}

@ -6,24 +6,25 @@ import { ServiceHelpers } from './service.helpers';
import { ISearchMovieResult } from '../interfaces/ISearchMovieResult';
@Injectable()
export class SearchService {
constructor(private http: Http) {
export class SearchService extends ServiceHelpers {
constructor(http: Http) {
super(http, "/api/v1/search");
}
searchMovie(searchTerm: string): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/' + searchTerm).map(ServiceHelpers.extractData);
return this.http.get(`${this.url}/Movie/` + searchTerm).map(this.extractData);
}
popularMovies(): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/Popular').map(ServiceHelpers.extractData);
return this.http.get(`${this.url}/Movie/Popular`).map(this.extractData);
}
upcomignMovies(): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/upcoming').map(ServiceHelpers.extractData);
return this.http.get(`${this.url}/Movie/upcoming`).map(this.extractData);
}
nowPlayingMovies(): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/nowplaying').map(ServiceHelpers.extractData);
return this.http.get(`${this.url}/Movie/nowplaying`).map(this.extractData);
}
topRatedMovies(): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/toprated').map(ServiceHelpers.extractData);
return this.http.get(`${this.url}/Movie/toprated`).map(this.extractData);
}
}

@ -1,15 +1,29 @@
import { Headers, RequestOptions, Response } from '@angular/http';
import { Headers, Response, Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
export class ServiceHelpers {
public static Headers = new Headers({ 'Content-Type': 'application/json' });
public static RequestOptions = new RequestOptions({
headers: ServiceHelpers.Headers
});
constructor(protected http: Http, protected url: string) {
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json; charset=utf-8');
}
protected headers: Headers;
public static extractData(res: Response) {
console.log(res);
return res.json();
protected extractData(res: Response) {
let body = res.json();
//console.log('extractData', body || {});
return body || {};
}
protected handleError(error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
Loading…
Cancel
Save