mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Adding a search API.
This commit is contained in:
parent
729a58ad2f
commit
c84eac21d2
@ -1,17 +1,17 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
import { BrowseComponent } from './browse/browse.component';
|
import { BrowseComponent } from './browse/browse.component';
|
||||||
import { ShowDetailsComponent } from './show-details/show-details.component';
|
|
||||||
import { NotFoundComponent } from './not-found/not-found.component';
|
|
||||||
import { ShowResolverService } from './services/show-resolver.service';
|
|
||||||
import { LibraryResolverService } from './services/library-resolver.service';
|
|
||||||
import { PlayerComponent } from "./player/player.component";
|
|
||||||
import { StreamResolverService } from "./services/stream-resolver.service";
|
|
||||||
import { CollectionComponent } from "./collection/collection.component";
|
import { CollectionComponent } from "./collection/collection.component";
|
||||||
|
import { NotFoundComponent } from './not-found/not-found.component';
|
||||||
|
import { PlayerComponent } from "./player/player.component";
|
||||||
|
import { SearchComponent } from "./search/search.component";
|
||||||
import { CollectionResolverService } from "./services/collection-resolver.service";
|
import { CollectionResolverService } from "./services/collection-resolver.service";
|
||||||
|
import { LibraryResolverService } from './services/library-resolver.service';
|
||||||
import { PeopleResolverService } from "./services/people-resolver.service";
|
import { PeopleResolverService } from "./services/people-resolver.service";
|
||||||
|
import { SearchResolverService } from "./services/search-resolver.service";
|
||||||
|
import { ShowResolverService } from './services/show-resolver.service';
|
||||||
|
import { StreamResolverService } from "./services/stream-resolver.service";
|
||||||
|
import { ShowDetailsComponent } from './show-details/show-details.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: "browse", component: BrowseComponent, pathMatch: "full", resolve: { shows: LibraryResolverService } },
|
{ path: "browse", component: BrowseComponent, pathMatch: "full", resolve: { shows: LibraryResolverService } },
|
||||||
@ -19,7 +19,8 @@ const routes: Routes = [
|
|||||||
{ path: "show/:show-slug", component: ShowDetailsComponent, resolve: { show: ShowResolverService } },
|
{ path: "show/:show-slug", component: ShowDetailsComponent, resolve: { show: ShowResolverService } },
|
||||||
{ path: "collection/:collection-slug", component: CollectionComponent, resolve: { collection: CollectionResolverService } },
|
{ path: "collection/:collection-slug", component: CollectionComponent, resolve: { collection: CollectionResolverService } },
|
||||||
{ path: "people/:people-slug", component: CollectionComponent, resolve: { collection: PeopleResolverService } },
|
{ path: "people/:people-slug", component: CollectionComponent, resolve: { collection: PeopleResolverService } },
|
||||||
{ path: "watch/:item", component: PlayerComponent, resolve: { item: StreamResolverService } },
|
{ path: "watch/:item", component: PlayerComponent, resolve: { item: StreamResolverService } },
|
||||||
|
{ path: "search/:query", component: SearchComponent, resolve: { items: SearchResolverService } },
|
||||||
{ path: "**", component: NotFoundComponent }
|
{ path: "**", component: NotFoundComponent }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul class="navbar-nav flex-row ml-auto">
|
<ul class="navbar-nav flex-row ml-auto">
|
||||||
<li class="nav-item icon">
|
<li class="nav-item icon searchbar">
|
||||||
<mat-icon matTooltipPosition="below" matTooltip="Search">search</mat-icon>
|
<input placeholder="Search" id="search" type="search" (oninit)="onUpdateValue(this.value)"/>
|
||||||
|
<mat-icon matTooltipPosition="below" matTooltip="Search" (click)="openSearch()">search</mat-icon>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="icon" routerLink="/login" routerLinkActive="active" matTooltipPosition="below" matTooltip="Login">
|
<a class="icon" routerLink="/login" routerLinkActive="active" matTooltipPosition="below" matTooltip="Login">
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
@import "~bootstrap/scss/functions";
|
||||||
|
@import "~bootstrap/scss/variables";
|
||||||
|
@import "~bootstrap/scss/mixins/breakpoints";
|
||||||
|
|
||||||
.navbar
|
.navbar
|
||||||
{
|
{
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
@ -35,6 +39,33 @@
|
|||||||
color: var(--accentColor);
|
color: var(--accentColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.searchbar
|
||||||
|
{
|
||||||
|
border-radius: 30px;
|
||||||
|
|
||||||
|
> input
|
||||||
|
{
|
||||||
|
background: none !important;
|
||||||
|
color: white;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid #cfcfcf;
|
||||||
|
width: 0;
|
||||||
|
padding: 0;
|
||||||
|
transition: width 0.4s ease-in-out;
|
||||||
|
|
||||||
|
&:focus, .searching
|
||||||
|
{
|
||||||
|
width: 12rem;
|
||||||
|
|
||||||
|
@include media-breakpoint-up(sm)
|
||||||
|
{
|
||||||
|
width: 20rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.icon
|
.icon
|
||||||
{
|
{
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
|
@ -39,6 +39,19 @@ export class AppComponent
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openSearch()
|
||||||
|
{
|
||||||
|
let input = <HTMLInputElement>document.getElementById("search");
|
||||||
|
|
||||||
|
input.value = "";
|
||||||
|
input.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdateValue(value: string)
|
||||||
|
{
|
||||||
|
console.log("Value: " + value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Library
|
interface Library
|
||||||
|
@ -19,6 +19,7 @@ import { EpisodesListComponent } from './episodes-list/episodes-list.component';
|
|||||||
import { NotFoundComponent } from './not-found/not-found.component';
|
import { NotFoundComponent } from './not-found/not-found.component';
|
||||||
import { PlayerComponent } from './player/player.component';
|
import { PlayerComponent } from './player/player.component';
|
||||||
import { ShowDetailsComponent } from './show-details/show-details.component';
|
import { ShowDetailsComponent } from './show-details/show-details.component';
|
||||||
|
import { SearchComponent } from './search/search.component';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -29,7 +30,8 @@ import { ShowDetailsComponent } from './show-details/show-details.component';
|
|||||||
ShowDetailsComponent,
|
ShowDetailsComponent,
|
||||||
EpisodesListComponent,
|
EpisodesListComponent,
|
||||||
PlayerComponent,
|
PlayerComponent,
|
||||||
CollectionComponent
|
CollectionComponent,
|
||||||
|
SearchComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@import "~bootstrap//scss/functions";
|
@import "~bootstrap/scss/functions";
|
||||||
@import "~bootstrap/scss/variables";
|
@import "~bootstrap/scss/variables";
|
||||||
@import "~bootstrap/scss//mixins/breakpoints";
|
@import "~bootstrap/scss/mixins/breakpoints";
|
||||||
|
|
||||||
button
|
button
|
||||||
{
|
{
|
||||||
|
1
Kyoo/ClientApp/src/app/search/search.component.html
Normal file
1
Kyoo/ClientApp/src/app/search/search.component.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<p>search works!</p>
|
0
Kyoo/ClientApp/src/app/search/search.component.scss
Normal file
0
Kyoo/ClientApp/src/app/search/search.component.scss
Normal file
25
Kyoo/ClientApp/src/app/search/search.component.spec.ts
Normal file
25
Kyoo/ClientApp/src/app/search/search.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SearchComponent } from './search.component';
|
||||||
|
|
||||||
|
describe('SearchComponent', () => {
|
||||||
|
let component: SearchComponent;
|
||||||
|
let fixture: ComponentFixture<SearchComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ SearchComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(SearchComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
20
Kyoo/ClientApp/src/app/search/search.component.ts
Normal file
20
Kyoo/ClientApp/src/app/search/search.component.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute } from "@angular/router";
|
||||||
|
import { SearchResut } from "../../models/search-result";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-search',
|
||||||
|
templateUrl: './search.component.html',
|
||||||
|
styleUrls: ['./search.component.scss']
|
||||||
|
})
|
||||||
|
export class SearchComponent implements OnInit
|
||||||
|
{
|
||||||
|
items: SearchResut;
|
||||||
|
|
||||||
|
constructor(private route: ActivatedRoute) { }
|
||||||
|
|
||||||
|
ngOnInit()
|
||||||
|
{
|
||||||
|
this.items = this.route.snapshot.data.items;
|
||||||
|
}
|
||||||
|
}
|
26
Kyoo/ClientApp/src/app/services/search-resolver.service.ts
Normal file
26
Kyoo/ClientApp/src/app/services/search-resolver.service.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
|
import { ActivatedRouteSnapshot, Resolve } from '@angular/router';
|
||||||
|
import { EMPTY, Observable } from 'rxjs';
|
||||||
|
import { catchError } from 'rxjs/operators';
|
||||||
|
import { SearchResut } from "../../models/search-result";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class SearchResolverService implements Resolve<SearchResut>
|
||||||
|
{
|
||||||
|
constructor(private http: HttpClient, private snackBar: MatSnackBar) { }
|
||||||
|
|
||||||
|
resolve(route: ActivatedRouteSnapshot): SearchResut | Observable<SearchResut> | Promise<SearchResut>
|
||||||
|
{
|
||||||
|
let query: string = route.paramMap.get("query");
|
||||||
|
return this.http.get<SearchResut>("api/search/" + query).pipe(catchError((error: HttpErrorResponse) =>
|
||||||
|
{
|
||||||
|
console.log(error.status + " - " + error.message);
|
||||||
|
this.snackBar.open("An unknow error occured.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||||
|
return EMPTY;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
3
Kyoo/ClientApp/src/models/search-result.js
Normal file
3
Kyoo/ClientApp/src/models/search-result.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
//# sourceMappingURL=search-result.js.map
|
1
Kyoo/ClientApp/src/models/search-result.js.map
Normal file
1
Kyoo/ClientApp/src/models/search-result.js.map
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"search-result.js","sourceRoot":"","sources":["search-result.ts"],"names":[],"mappings":""}
|
14
Kyoo/ClientApp/src/models/search-result.ts
Normal file
14
Kyoo/ClientApp/src/models/search-result.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { Show } from "./show";
|
||||||
|
import { Episode } from "./episode";
|
||||||
|
import { People } from "./people";
|
||||||
|
import { Studio } from "./studio";
|
||||||
|
import { Genre } from "./genre";
|
||||||
|
|
||||||
|
export interface SearchResut
|
||||||
|
{
|
||||||
|
shows: Show[];
|
||||||
|
episodes: Episode[];
|
||||||
|
people: People[];
|
||||||
|
genres: Genre[];
|
||||||
|
studios: Studio[];
|
||||||
|
}
|
32
Kyoo/Controllers/SearchController.cs
Normal file
32
Kyoo/Controllers/SearchController.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using Kyoo.InternalAPI;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class SearchController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILibraryManager libraryManager;
|
||||||
|
|
||||||
|
public SearchController(ILibraryManager libraryManager)
|
||||||
|
{
|
||||||
|
this.libraryManager = libraryManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{query}")]
|
||||||
|
public ActionResult<SearchResult> Search(string query)
|
||||||
|
{
|
||||||
|
SearchResult result = new SearchResult
|
||||||
|
{
|
||||||
|
shows = libraryManager.GetShows(query),
|
||||||
|
episodes = libraryManager.SearchEpisodes(query),
|
||||||
|
people = libraryManager.SearchPeople(query),
|
||||||
|
genres = libraryManager.SearchGenres(query),
|
||||||
|
studios = libraryManager.SearchStudios(query)
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -134,7 +134,6 @@ namespace Kyoo.Controllers
|
|||||||
lines[1] = lines[1].Replace(',', '.');
|
lines[1] = lines[1].Replace(',', '.');
|
||||||
if (lines[2].Length > 5)
|
if (lines[2].Length > 5)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("&Line2 sub: " + lines[2].Substring(0, 6));
|
|
||||||
switch (lines[2].Substring(0, 6))
|
switch (lines[2].Substring(0, 6))
|
||||||
{
|
{
|
||||||
case "{\\an1}":
|
case "{\\an1}":
|
||||||
|
@ -280,7 +280,7 @@ namespace Kyoo.InternalAPI
|
|||||||
case ".ass":
|
case ".ass":
|
||||||
codec = "ass";
|
codec = "ass";
|
||||||
break;
|
break;
|
||||||
case ".str":
|
case ".srt":
|
||||||
codec = "subrip";
|
codec = "subrip";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -8,7 +8,6 @@ namespace Kyoo.InternalAPI
|
|||||||
{
|
{
|
||||||
//Read values
|
//Read values
|
||||||
string GetShowExternalIDs(long showID);
|
string GetShowExternalIDs(long showID);
|
||||||
IEnumerable<Show> GetShows();
|
|
||||||
Studio GetStudio(long showID);
|
Studio GetStudio(long showID);
|
||||||
List<People> GetDirectors(long showID);
|
List<People> GetDirectors(long showID);
|
||||||
List<People> GetPeople(long showID);
|
List<People> GetPeople(long showID);
|
||||||
@ -25,6 +24,8 @@ namespace Kyoo.InternalAPI
|
|||||||
Track GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag, bool forced);
|
Track GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag, bool forced);
|
||||||
|
|
||||||
//Public read
|
//Public read
|
||||||
|
IEnumerable<Show> GetShows();
|
||||||
|
IEnumerable<Show> GetShows(string searchQuery);
|
||||||
Library GetLibrary(string librarySlug);
|
Library GetLibrary(string librarySlug);
|
||||||
IEnumerable<Library> GetLibraries();
|
IEnumerable<Library> GetLibraries();
|
||||||
Show GetShowBySlug(string slug);
|
Show GetShowBySlug(string slug);
|
||||||
@ -38,6 +39,10 @@ namespace Kyoo.InternalAPI
|
|||||||
Studio GetStudioBySlug(string slug);
|
Studio GetStudioBySlug(string slug);
|
||||||
Collection GetCollection(string slug);
|
Collection GetCollection(string slug);
|
||||||
IEnumerable<Episode> GetAllEpisodes();
|
IEnumerable<Episode> GetAllEpisodes();
|
||||||
|
IEnumerable<Episode> SearchEpisodes(string searchQuery);
|
||||||
|
IEnumerable<People> SearchPeople(string searchQuery);
|
||||||
|
IEnumerable<Genre> SearchGenres(string searchQuery);
|
||||||
|
IEnumerable<Studio> SearchStudios(string searchQuery);
|
||||||
|
|
||||||
//Check if value exists
|
//Check if value exists
|
||||||
bool IsCollectionRegistered(string collectionSlug);
|
bool IsCollectionRegistered(string collectionSlug);
|
||||||
|
@ -302,6 +302,22 @@ namespace Kyoo.InternalAPI
|
|||||||
return shows;
|
return shows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Show> GetShows(string searchQuery)
|
||||||
|
{
|
||||||
|
List<Show> shows = new List<Show>();
|
||||||
|
SQLiteDataReader reader;
|
||||||
|
string query = "SELECT slug, title, aliases, startYear, endYear, '0' FROM (SELECT slug, title, aliases, startYear, endYear, '0' FROM shows LEFT JOIN collectionsLinks l ON l.showID = shows.id WHERE l.showID IS NULL UNION SELECT slug, name, null, startYear, endYear, '1' FROM collections) WHERE title LIKE $query OR aliases LIKE $query ORDER BY title;";
|
||||||
|
|
||||||
|
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("$query", "%" + searchQuery + "%");
|
||||||
|
reader = cmd.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
shows.Add(Show.FromQueryReader(reader, true));
|
||||||
|
}
|
||||||
|
return shows;
|
||||||
|
}
|
||||||
|
|
||||||
public Show GetShowBySlug(string slug)
|
public Show GetShowBySlug(string slug)
|
||||||
{
|
{
|
||||||
string query = "SELECT * FROM shows WHERE slug = $slug;";
|
string query = "SELECT * FROM shows WHERE slug = $slug;";
|
||||||
@ -661,6 +677,70 @@ namespace Kyoo.InternalAPI
|
|||||||
return episodes;
|
return episodes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Episode> SearchEpisodes(string searchQuery)
|
||||||
|
{
|
||||||
|
List<Episode> episodes = new List<Episode>();
|
||||||
|
SQLiteDataReader reader;
|
||||||
|
string query = "SELECT * FROM episodes WHERE title LIKE $query ORDER BY seasonNumber, episodeNumber;";
|
||||||
|
|
||||||
|
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("$query", "%" + searchQuery + "%");
|
||||||
|
reader = cmd.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
episodes.Add(Episode.FromReader(reader));
|
||||||
|
}
|
||||||
|
return episodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<People> SearchPeople(string searchQuery)
|
||||||
|
{
|
||||||
|
List<People> people = new List<People>();
|
||||||
|
SQLiteDataReader reader;
|
||||||
|
string query = "SELECT * FROM people WHERE name LIKE $query ORDER BY name;";
|
||||||
|
|
||||||
|
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("$query", "%" + searchQuery + "%");
|
||||||
|
reader = cmd.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
people.Add(People.FromReader(reader));
|
||||||
|
}
|
||||||
|
return people;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Genre> SearchGenres(string searchQuery)
|
||||||
|
{
|
||||||
|
List<Genre> genres = new List<Genre>();
|
||||||
|
SQLiteDataReader reader;
|
||||||
|
string query = "SELECT * FROM genres WHERE name LIKE $query ORDER BY name;";
|
||||||
|
|
||||||
|
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("$query", "%" + searchQuery + "%");
|
||||||
|
reader = cmd.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
genres.Add(Genre.FromReader(reader));
|
||||||
|
}
|
||||||
|
return genres;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Studio> SearchStudios(string searchQuery)
|
||||||
|
{
|
||||||
|
List<Studio> studios = new List<Studio>();
|
||||||
|
SQLiteDataReader reader;
|
||||||
|
string query = "SELECT * FROM studios WHERE name LIKE $query ORDER BY name;";
|
||||||
|
|
||||||
|
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("$query", "%" + searchQuery + "%");
|
||||||
|
reader = cmd.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
studios.Add(Studio.FromReader(reader));
|
||||||
|
}
|
||||||
|
return studios;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Check if items exists
|
#region Check if items exists
|
||||||
|
@ -25,37 +25,49 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
|||||||
string localBackdrop = Path.Combine(show.Path, "backdrop.jpg");
|
string localBackdrop = Path.Combine(show.Path, "backdrop.jpg");
|
||||||
|
|
||||||
|
|
||||||
if (show.ImgPrimary != null)
|
if (show.ImgPrimary != null && !File.Exists(localThumb))
|
||||||
{
|
{
|
||||||
if (!File.Exists(localThumb))
|
try
|
||||||
{
|
{
|
||||||
using (WebClient client = new WebClient())
|
using (WebClient client = new WebClient())
|
||||||
{
|
{
|
||||||
await client.DownloadFileTaskAsync(new Uri(show.ImgPrimary), localThumb);
|
await client.DownloadFileTaskAsync(new Uri(show.ImgPrimary), localThumb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (WebException)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Couldn't download an image.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show.ImgLogo != null)
|
if (show.ImgLogo != null && !File.Exists(localLogo))
|
||||||
{
|
{
|
||||||
if (!File.Exists(localLogo))
|
try
|
||||||
{
|
{
|
||||||
using (WebClient client = new WebClient())
|
using (WebClient client = new WebClient())
|
||||||
{
|
{
|
||||||
await client.DownloadFileTaskAsync(new Uri(show.ImgLogo), localLogo);
|
await client.DownloadFileTaskAsync(new Uri(show.ImgLogo), localLogo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (WebException)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Couldn't download an image.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show.ImgBackdrop != null)
|
if (show.ImgBackdrop != null && !File.Exists(localBackdrop))
|
||||||
{
|
{
|
||||||
if (!File.Exists(localBackdrop))
|
try
|
||||||
{
|
{
|
||||||
using (WebClient client = new WebClient())
|
using (WebClient client = new WebClient())
|
||||||
{
|
{
|
||||||
await client.DownloadFileTaskAsync(new Uri(show.ImgBackdrop), localBackdrop);
|
await client.DownloadFileTaskAsync(new Uri(show.ImgBackdrop), localBackdrop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (WebException)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Couldn't download an image.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return show;
|
return show;
|
||||||
@ -71,10 +83,16 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
|||||||
string localThumb = root + "/" + people[i].slug + ".jpg";
|
string localThumb = root + "/" + people[i].slug + ".jpg";
|
||||||
if (people[i].imgPrimary != null && !File.Exists(localThumb))
|
if (people[i].imgPrimary != null && !File.Exists(localThumb))
|
||||||
{
|
{
|
||||||
using (WebClient client = new WebClient())
|
try
|
||||||
{
|
{
|
||||||
Debug.WriteLine("&" + localThumb);
|
using (WebClient client = new WebClient())
|
||||||
await client.DownloadFileTaskAsync(new Uri(people[i].imgPrimary), localThumb);
|
{
|
||||||
|
await client.DownloadFileTaskAsync(new Uri(people[i].imgPrimary), localThumb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (WebException)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Couldn't download an image.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,9 +106,16 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
|||||||
string localThumb = episode.Path.Replace(Path.GetExtension(episode.Path), "-thumb.jpg");
|
string localThumb = episode.Path.Replace(Path.GetExtension(episode.Path), "-thumb.jpg");
|
||||||
if (episode.ImgPrimary != null && !File.Exists(localThumb))
|
if (episode.ImgPrimary != null && !File.Exists(localThumb))
|
||||||
{
|
{
|
||||||
using (WebClient client = new WebClient())
|
try
|
||||||
{
|
{
|
||||||
await client.DownloadFileTaskAsync(new Uri(episode.ImgPrimary), localThumb);
|
using (WebClient client = new WebClient())
|
||||||
|
{
|
||||||
|
await client.DownloadFileTaskAsync(new Uri(episode.ImgPrimary), localThumb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (WebException)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Couldn't download an image.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
<None Remove="ClientApp\src\models\collection.ts" />
|
<None Remove="ClientApp\src\models\collection.ts" />
|
||||||
<None Remove="ClientApp\src\models\genre.ts" />
|
<None Remove="ClientApp\src\models\genre.ts" />
|
||||||
<None Remove="ClientApp\src\models\people.ts" />
|
<None Remove="ClientApp\src\models\people.ts" />
|
||||||
|
<None Remove="ClientApp\src\models\search-result.ts" />
|
||||||
<None Remove="ClientApp\src\models\show.ts" />
|
<None Remove="ClientApp\src\models\show.ts" />
|
||||||
<None Remove="ClientApp\src\models\studio.ts" />
|
<None Remove="ClientApp\src\models\studio.ts" />
|
||||||
<None Remove="ClientApp\src\models\watch-item.ts" />
|
<None Remove="ClientApp\src\models\watch-item.ts" />
|
||||||
@ -77,6 +78,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<TypeScriptCompile Include="ClientApp\src\models\search-result.ts">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</TypeScriptCompile>
|
||||||
<TypeScriptCompile Include="ClientApp\src\models\collection.ts" />
|
<TypeScriptCompile Include="ClientApp\src\models\collection.ts" />
|
||||||
<TypeScriptCompile Include="ClientApp\src\models\genre.ts" />
|
<TypeScriptCompile Include="ClientApp\src\models\genre.ts" />
|
||||||
<TypeScriptCompile Include="ClientApp\src\models\people.ts" />
|
<TypeScriptCompile Include="ClientApp\src\models\people.ts" />
|
||||||
|
13
Kyoo/Models/SearchResult.cs
Normal file
13
Kyoo/Models/SearchResult.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Kyoo.Models
|
||||||
|
{
|
||||||
|
public class SearchResult
|
||||||
|
{
|
||||||
|
public IEnumerable<Show> shows;
|
||||||
|
public IEnumerable<Episode> episodes;
|
||||||
|
public IEnumerable<People> people;
|
||||||
|
public IEnumerable<Genre> genres;
|
||||||
|
public IEnumerable<Studio> studios;
|
||||||
|
}
|
||||||
|
}
|
@ -91,9 +91,9 @@ namespace Kyoo.Models
|
|||||||
IsCollection = false;
|
IsCollection = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Show FromQueryReader(System.Data.SQLite.SQLiteDataReader reader)
|
public static Show FromQueryReader(System.Data.SQLite.SQLiteDataReader reader, bool containsAliases = false)
|
||||||
{
|
{
|
||||||
return new Show()
|
Show show = new Show()
|
||||||
{
|
{
|
||||||
Slug = reader["slug"] as string,
|
Slug = reader["slug"] as string,
|
||||||
Title = reader["title"] as string,
|
Title = reader["title"] as string,
|
||||||
@ -101,6 +101,9 @@ namespace Kyoo.Models
|
|||||||
EndYear = reader["endYear"] as long?,
|
EndYear = reader["endYear"] as long?,
|
||||||
IsCollection = reader["'0'"] as string == "1"
|
IsCollection = reader["'0'"] as string == "1"
|
||||||
};
|
};
|
||||||
|
if (containsAliases)
|
||||||
|
show.Aliases = (reader["aliases"] as string)?.Split('|');
|
||||||
|
return show;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Show FromReader(System.Data.SQLite.SQLiteDataReader reader)
|
public static Show FromReader(System.Data.SQLite.SQLiteDataReader reader)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user