mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-08 10:44:20 -04:00
Now using the genre table inside the database. Adding menus inside the show details component of the webapp.
This commit is contained in:
parent
373c05e3c5
commit
26edab07b0
@ -10,6 +10,8 @@ import { ShowDetailsComponent } from './show-details/show-details.component';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -24,7 +26,9 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
AppRoutingModule,
|
||||
BrowserAnimationsModule,
|
||||
MatSnackBarModule,
|
||||
MatProgressBarModule
|
||||
MatProgressBarModule,
|
||||
MatButtonModule,
|
||||
MatDividerModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
@ -1,12 +1,48 @@
|
||||
<div class="container pt-5">
|
||||
<div class="row">
|
||||
<img class="poster" src="thumb/{{this.show.slug}}" />
|
||||
<div class="main">
|
||||
<div class="info">
|
||||
<h1>{{this.show.title}}</h1>
|
||||
<h6 *ngIf="show.endYear; else elseBlock">{{show.startYear}} - {{show.endYear}}</h6>
|
||||
<ng-template #elseBlock><h2>{{show.startYear}}</h2></ng-template>
|
||||
</div>
|
||||
<!--<mat-divider></mat-divider>-->
|
||||
<div class="buttons">
|
||||
<button mat-fab>Play</button>
|
||||
<button mat-mini-fab>Download</button>
|
||||
<button mat-mini-fab>Watched</button>
|
||||
<button mat-mini-fab>More</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pt-3">
|
||||
<div class="col">
|
||||
<p class="text-justify">{{this.show.overview}}</p>
|
||||
</div>
|
||||
<mat-divider vertical></mat-divider>
|
||||
<div class="col-2">
|
||||
<h3>Genres</h3>
|
||||
<ul>
|
||||
<li *ngFor="let genre of this.show.genres"><a routerLink="/genre/{{genre.slug}}">{{genre.name}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bg-primary" style="display: block;"> <!--For now we'll leave that for wireframing a bit-->
|
||||
<h3>Staff</h3>
|
||||
<div class="scroll-row" style="position: relative;">
|
||||
<button mat-fab id="leftBtn"></button>
|
||||
<div class="justify-content-left people-container">
|
||||
<a class="people" *ngFor="let people of this.show.people" routerLink="/people/{{people.slug}}">
|
||||
<img [style.background-image]="getPeopleIcon(people.slug)" />
|
||||
<p class="title">{{people.name}}</p>
|
||||
<p class="role">{{people.role}}</p>
|
||||
</a>
|
||||
</div>
|
||||
<button mat-fab id="rightBtn"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<p>{{this.show.overview}}</p>
|
||||
</div>
|
||||
|
@ -2,18 +2,112 @@
|
||||
{
|
||||
width: 25%;
|
||||
background-color: #333333;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.info
|
||||
{
|
||||
display: inline-block;
|
||||
padding-left: 2.5em;
|
||||
padding-bottom: 7em;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.main
|
||||
{
|
||||
align-self: end;
|
||||
padding-bottom: 5em;
|
||||
padding-left: 2.5em;
|
||||
|
||||
.info
|
||||
{
|
||||
}
|
||||
|
||||
.buttons
|
||||
{
|
||||
> button
|
||||
{
|
||||
outline: none;
|
||||
margin: .3em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.people-container
|
||||
{
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.people
|
||||
{
|
||||
width: 15%;
|
||||
margin: 1em;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
outline: none;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
|
||||
/*@include media-breakpoint-up(md)
|
||||
{
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg)
|
||||
{
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(xl)
|
||||
{
|
||||
width: 18%;
|
||||
}*/
|
||||
/*&:focus, &:hover
|
||||
{
|
||||
> img
|
||||
{
|
||||
outline: solid var(--accentColor);
|
||||
}
|
||||
|
||||
> .title
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
}*/
|
||||
> img
|
||||
{
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-top: 147.0588%;
|
||||
background-size: cover;
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
> p
|
||||
{
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
margin-bottom: 0px;
|
||||
|
||||
&.role
|
||||
{
|
||||
opacity: 0.8;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover
|
||||
{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
#leftBtn
|
||||
{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 33%;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#rightBtn
|
||||
{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 33%;
|
||||
outline: none;
|
||||
}
|
||||
|
@ -19,6 +19,11 @@ export class ShowDetailsComponent implements OnInit
|
||||
document.body.style.backgroundImage = "url(/backdrop/" + this.show.slug + ")";
|
||||
}
|
||||
|
||||
getPeopleIcon(slug: string)
|
||||
{
|
||||
return this.sanitizer.bypassSecurityTrustStyle("url(/peopleimg/" + slug + ")");
|
||||
}
|
||||
|
||||
getBackdrop()
|
||||
{
|
||||
return this.sanitizer.bypassSecurityTrustStyle("url(/backdrop/" + this.show.slug + ")");
|
||||
|
@ -36,3 +36,9 @@ $theme: mat-light-theme($primary, $accent);
|
||||
background-color: theme-color("accentColor");
|
||||
color: theme-color("textPrimary");
|
||||
}
|
||||
|
||||
.scroll-row
|
||||
{
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
using Kyoo.InternalAPI;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
{
|
||||
@ -32,5 +31,15 @@ namespace Kyoo.Controllers
|
||||
|
||||
return new PhysicalFileResult(thumbPath, "image/jpg");
|
||||
}
|
||||
|
||||
[HttpGet("peopleimg/{peopleSlug}")]
|
||||
public IActionResult GetPeopleIcon(string peopleSlug)
|
||||
{
|
||||
string thumbPath = libraryManager.GetPeopleBySlug(peopleSlug)?.imgPrimary;
|
||||
if (thumbPath == null)
|
||||
return NotFound();
|
||||
|
||||
return new PhysicalFileResult(thumbPath, "image/jpg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,13 @@ namespace Kyoo.InternalAPI
|
||||
string GetShowExternalIDs(long showID);
|
||||
IEnumerable<Show> QueryShows(string selection);
|
||||
List<People> GetPeople(long showID);
|
||||
List<Genre> GetGenreForShow(long showID);
|
||||
|
||||
//Public read
|
||||
IEnumerable<Library> GetLibraries();
|
||||
Show GetShowBySlug(string slug);
|
||||
People GetPeopleBySlug(string slug);
|
||||
Genre GetGenreBySlug(string slug);
|
||||
|
||||
//Check if value exists
|
||||
bool IsShowRegistered(string showPath);
|
||||
@ -26,6 +29,8 @@ namespace Kyoo.InternalAPI
|
||||
long RegisterSeason(Season season);
|
||||
long RegisterEpisode(Episode episode);
|
||||
|
||||
long GetOrCreateGenre(Genre genre);
|
||||
|
||||
void RegisterShowPeople(long showID, List<People> actors);
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ namespace Kyoo.InternalAPI
|
||||
aliases TEXT,
|
||||
path TEXT UNIQUE,
|
||||
overview TEXT,
|
||||
genres TEXT,
|
||||
status TEXT,
|
||||
startYear INTEGER,
|
||||
endYear INTEGER,
|
||||
@ -224,7 +223,7 @@ namespace Kyoo.InternalAPI
|
||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
if (reader.Read())
|
||||
return Show.FromReader(reader).SetPeople(this);
|
||||
return Show.FromReader(reader).SetGenres(this).SetPeople(this);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
@ -242,11 +241,61 @@ namespace Kyoo.InternalAPI
|
||||
List<People> people = new List<People>();
|
||||
|
||||
while (reader.Read())
|
||||
people.Add(People.FromReader(reader));
|
||||
people.Add(People.FromFullReader(reader));
|
||||
|
||||
return people;
|
||||
}
|
||||
}
|
||||
|
||||
public People GetPeopleBySlug(string slug)
|
||||
{
|
||||
string query = "SELECT * FROM people WHERE slug = $slug;";
|
||||
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("$slug", slug);
|
||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
if (reader.Read())
|
||||
return People.FromReader(reader);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Genre> GetGenreForShow(long showID)
|
||||
{
|
||||
string query = "SELECT genres.id, genres.slug, genres.name FROM genres JOIN genresLinks l ON l.genreID = genres.id WHERE l.showID = $showID;";
|
||||
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("$showID", showID);
|
||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
List<Genre> genres = new List<Genre>();
|
||||
|
||||
while (reader.Read())
|
||||
genres.Add(Genre.FromReader(reader));
|
||||
|
||||
return genres;
|
||||
}
|
||||
}
|
||||
|
||||
public Genre GetGenreBySlug(string slug)
|
||||
{
|
||||
string query = "SELECT * FROM genres WHERE slug = $slug;";
|
||||
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("$slug", slug);
|
||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
if (reader.Read())
|
||||
return Genre.FromReader(reader);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Check if items exists
|
||||
@ -308,12 +357,31 @@ namespace Kyoo.InternalAPI
|
||||
return cmd.ExecuteScalar() != null;
|
||||
}
|
||||
}
|
||||
|
||||
public long GetOrCreateGenre(Genre genre)
|
||||
{
|
||||
Genre existingGenre = GetGenreBySlug(genre.Slug);
|
||||
|
||||
if (existingGenre != null)
|
||||
return existingGenre.id;
|
||||
|
||||
string query = "INSERT INTO genres (slug, name) VALUES($slug, $name);";
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("$slug", genre.Slug);
|
||||
cmd.Parameters.AddWithValue("$name", genre.Name);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
cmd.CommandText = "SELECT LAST_INSERT_ROWID()";
|
||||
return (long)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Write Into The Database
|
||||
public long RegisterShow(Show show)
|
||||
{
|
||||
string query = "INSERT INTO shows (slug, title, aliases, path, overview, genres, startYear, endYear, imgPrimary, imgThumb, imgLogo, imgBackdrop, externalIDs) VALUES($slug, $title, $aliases, $path, $overview, $genres, $startYear, $endYear, $imgPrimary, $imgThumb, $imgLogo, $imgBackdrop, $externalIDs);";
|
||||
string query = "INSERT INTO shows (slug, title, aliases, path, overview, startYear, endYear, imgPrimary, imgThumb, imgLogo, imgBackdrop, externalIDs) VALUES($slug, $title, $aliases, $path, $overview, $startYear, $endYear, $imgPrimary, $imgThumb, $imgLogo, $imgBackdrop, $externalIDs);";
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("$slug", show.Slug);
|
||||
@ -321,7 +389,6 @@ namespace Kyoo.InternalAPI
|
||||
cmd.Parameters.AddWithValue("$aliases", show.GetAliases());
|
||||
cmd.Parameters.AddWithValue("$path", show.Path);
|
||||
cmd.Parameters.AddWithValue("$overview", show.Overview);
|
||||
cmd.Parameters.AddWithValue("$genres", show.GetGenres());
|
||||
cmd.Parameters.AddWithValue("$status", show.Status);
|
||||
cmd.Parameters.AddWithValue("$startYear", show.StartYear);
|
||||
cmd.Parameters.AddWithValue("$endYear", show.EndYear);
|
||||
@ -333,7 +400,18 @@ namespace Kyoo.InternalAPI
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
cmd.CommandText = "SELECT LAST_INSERT_ROWID()";
|
||||
return (long)cmd.ExecuteScalar();
|
||||
long showID = (long)cmd.ExecuteScalar();
|
||||
|
||||
cmd.CommandText = "INSERT INTO genresLinks (genreID, showID) VALUES($genreID, $showID);";
|
||||
foreach (Genre genre in show.Genres)
|
||||
{
|
||||
long genreID = GetOrCreateGenre(genre);
|
||||
cmd.Parameters.AddWithValue("$genreID", genreID);
|
||||
cmd.Parameters.AddWithValue("$showID", showID);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
return showID;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ namespace Kyoo.InternalAPI.MetadataProvider
|
||||
data.aliases,
|
||||
null, //Path
|
||||
data.overview,
|
||||
data.genre,
|
||||
GetGenres(data.genre),
|
||||
GetStatus(data.status),
|
||||
GetYear(data.firstAired),
|
||||
null, //endYear
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Kyoo.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
@ -68,5 +69,15 @@ namespace Kyoo.InternalAPI.MetadataProvider
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Genre> GetGenres(string[] input)
|
||||
{
|
||||
List<Genre> genres = new List<Genre>();
|
||||
|
||||
foreach (string genre in input)
|
||||
genres.Add(new Genre(ToSlug(genre), genre));
|
||||
|
||||
return genres;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
31
Kyoo/Models/Genre.cs
Normal file
31
Kyoo/Models/Genre.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Kyoo.Models
|
||||
{
|
||||
public class Genre
|
||||
{
|
||||
[JsonIgnore] public readonly long id;
|
||||
public string Slug;
|
||||
public string Name;
|
||||
|
||||
public Genre(string slug, string name)
|
||||
{
|
||||
Slug = slug;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public Genre(long id, string slug, string name)
|
||||
{
|
||||
this.id = id;
|
||||
Slug = slug;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public static Genre FromReader(System.Data.SQLite.SQLiteDataReader reader)
|
||||
{
|
||||
return new Genre((long)reader["id"],
|
||||
reader["slug"] as string,
|
||||
reader["name"] as string);
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,15 @@ namespace Kyoo.Models
|
||||
|
||||
public string externalIDs;
|
||||
|
||||
public People(long id, string slug, string name, string imgPrimary, string externalIDs)
|
||||
{
|
||||
this.id = id;
|
||||
this.slug = slug;
|
||||
Name = name;
|
||||
this.imgPrimary = imgPrimary;
|
||||
this.externalIDs = externalIDs;
|
||||
}
|
||||
|
||||
public People(long id, string slug, string name, string role, string type, string imgPrimary, string externalIDs)
|
||||
{
|
||||
this.id = id;
|
||||
@ -25,6 +34,15 @@ namespace Kyoo.Models
|
||||
}
|
||||
|
||||
public static People FromReader(System.Data.SQLite.SQLiteDataReader reader)
|
||||
{
|
||||
return new People((long)reader["id"],
|
||||
reader["slug"] as string,
|
||||
reader["name"] as string,
|
||||
reader["imgPrimary"] as string,
|
||||
reader["externalIDs"] as string);
|
||||
}
|
||||
|
||||
public static People FromFullReader(System.Data.SQLite.SQLiteDataReader reader)
|
||||
{
|
||||
return new People((long)reader["id"],
|
||||
reader["slug"] as string,
|
||||
|
@ -14,7 +14,7 @@ namespace Kyoo.Models
|
||||
public IEnumerable<string> Aliases;
|
||||
[JsonIgnore] public string Path;
|
||||
public string Overview;
|
||||
public IEnumerable<string> Genres;
|
||||
public IEnumerable<Genre> Genres;
|
||||
public Status? Status;
|
||||
|
||||
public long? StartYear;
|
||||
@ -49,7 +49,7 @@ namespace Kyoo.Models
|
||||
|
||||
public Show() { }
|
||||
|
||||
public Show(long id, string slug, string title, IEnumerable<string> aliases, string path, string overview, IEnumerable<string> genres, Status? status, long? startYear, long? endYear, string externalIDs)
|
||||
public Show(long id, string slug, string title, IEnumerable<string> aliases, string path, string overview, IEnumerable<Genre> genres, Status? status, long? startYear, long? endYear, string externalIDs)
|
||||
{
|
||||
this.id = id;
|
||||
Slug = slug;
|
||||
@ -64,7 +64,7 @@ namespace Kyoo.Models
|
||||
ExternalIDs = externalIDs;
|
||||
}
|
||||
|
||||
public Show(long id, string slug, string title, IEnumerable<string> aliases, string path, string overview, IEnumerable<string> genres, Status? status, long? startYear, long? endYear, string imgPrimary, string imgThumb, string imgLogo, string imgBackdrop, string externalIDs)
|
||||
public Show(long id, string slug, string title, IEnumerable<string> aliases, string path, string overview, Status? status, long? startYear, long? endYear, string imgPrimary, string imgThumb, string imgLogo, string imgBackdrop, string externalIDs)
|
||||
{
|
||||
this.id = id;
|
||||
Slug = slug;
|
||||
@ -72,7 +72,6 @@ namespace Kyoo.Models
|
||||
Aliases = aliases;
|
||||
Path = path;
|
||||
Overview = overview;
|
||||
Genres = genres;
|
||||
Status = status;
|
||||
StartYear = startYear;
|
||||
EndYear = endYear;
|
||||
@ -91,7 +90,6 @@ namespace Kyoo.Models
|
||||
(reader["aliases"] as string)?.Split('|') ?? null,
|
||||
reader["path"] as string,
|
||||
reader["overview"] as string,
|
||||
(reader["genres"] as string)?.Split('|') ?? null,
|
||||
reader["status"] as Status?,
|
||||
reader["startYear"] as long?,
|
||||
reader["endYear"] as long?,
|
||||
@ -109,9 +107,9 @@ namespace Kyoo.Models
|
||||
return this;
|
||||
}
|
||||
|
||||
public Show SetPeople(People[] people)
|
||||
public Show SetGenres(ILibraryManager manager)
|
||||
{
|
||||
this.people = people;
|
||||
Genres = manager.GetGenreForShow(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user