configure grpc client + scanner fixes; need to figure out cors issue
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Grpc.AspNetCore" Version="2.64.0" />
|
<PackageReference Include="Grpc.AspNetCore" Version="2.64.0" />
|
||||||
|
<PackageReference Include="Grpc.AspNetCore.Web" Version="2.76.0" />
|
||||||
<PackageReference Include="MaybeError" Version="1.2.0" />
|
<PackageReference Include="MaybeError" Version="1.2.0" />
|
||||||
<PackageReference Include="MongoDB.Driver" Version="3.5.2" />
|
<PackageReference Include="MongoDB.Driver" Version="3.5.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ public partial class MediaEntry
|
|||||||
|
|
||||||
return new MediaEntry
|
return new MediaEntry
|
||||||
{
|
{
|
||||||
|
Version = 0,
|
||||||
CameraId = int.Parse(cam.Value),
|
CameraId = int.Parse(cam.Value),
|
||||||
Filepath = relativePath,
|
Filepath = relativePath,
|
||||||
Date = ParseDate(date.Value),
|
Date = ParseDate(date.Value),
|
||||||
|
|||||||
@@ -4,6 +4,21 @@ using AZKiServer.Services;
|
|||||||
using MongoDB.Driver;
|
using MongoDB.Driver;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
builder.WebHost.ConfigureKestrel(o =>
|
||||||
|
{
|
||||||
|
//o.Limits.MaxRequestBodySize = null;
|
||||||
|
#if !DEBUG
|
||||||
|
o.ListenAnyIP(8081, lo =>
|
||||||
|
{
|
||||||
|
lo.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
|
||||||
|
});
|
||||||
|
o.ListenAnyIP(8080, lo =>
|
||||||
|
{
|
||||||
|
lo.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
});
|
||||||
|
|
||||||
var config = builder.Configuration;
|
var config = builder.Configuration;
|
||||||
|
|
||||||
var dbString = config["DB_STRING"];
|
var dbString = config["DB_STRING"];
|
||||||
@@ -13,8 +28,8 @@ var db = dbClient.GetDatabase("AZKi");
|
|||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddSingleton(dbClient);
|
builder.Services.AddSingleton(dbClient);
|
||||||
builder.Services.AddSingleton<IMongoDatabase>(db);
|
builder.Services.AddSingleton<IMongoDatabase>(db);
|
||||||
builder.Services.AddGrpc();
|
|
||||||
builder.Services.AddControllers(opt => opt.ModelBinderProviders.Add(new BsonIdModelBinderProvider()));
|
builder.Services.AddControllers(opt => opt.ModelBinderProviders.Add(new BsonIdModelBinderProvider()));
|
||||||
|
builder.Services.AddGrpc();
|
||||||
builder.Services.AddHostedService<FileScannerService>();
|
builder.Services.AddHostedService<FileScannerService>();
|
||||||
builder.Services.AddTransient<MediaService>();
|
builder.Services.AddTransient<MediaService>();
|
||||||
|
|
||||||
@@ -38,8 +53,20 @@ builder.Services.AddCors(o =>
|
|||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
|
||||||
|
app.UseStaticFiles();
|
||||||
|
app.UseRouting();
|
||||||
|
app.UseCors();
|
||||||
|
|
||||||
|
|
||||||
|
//app.UseAuthentication();
|
||||||
|
//app.UseAuthorization();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
//app.MapGrpcService<GreeterService>();
|
app.MapControllers();
|
||||||
|
app.MapGrpcService<AZKiRpcService>()
|
||||||
|
.AllowAnonymous()
|
||||||
|
.RequireCors("RPC");
|
||||||
app.MapFallbackToFile("index.html");
|
app.MapFallbackToFile("index.html");
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public class AZKiRpcService(MediaService mediaService) : RPC.AZKi.AZKiBase
|
|||||||
var from = request.From.ToDateTime();
|
var from = request.From.ToDateTime();
|
||||||
var to = request.To.ToDateTime();
|
var to = request.To.ToDateTime();
|
||||||
var items = await mediaService.GetEntriesInRangeAsync(request.Type.FromRpc(), from, to);
|
var items = await mediaService.GetEntriesInRangeAsync(request.Type.FromRpc(), from, to);
|
||||||
|
|
||||||
var result = new MediaList();
|
var result = new MediaList();
|
||||||
result.Entries.AddRange(items.Select(e => e.ToRpc()));
|
result.Entries.AddRange(items.Select(e => e.ToRpc()));
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ public class FileScannerService(MediaService mediaService, IConfiguration config
|
|||||||
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var path = config["SCAN_PATH"];
|
var path = config["SCAN_LOCATION"];
|
||||||
if (string.IsNullOrWhiteSpace(path))
|
if (string.IsNullOrWhiteSpace(path))
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
_timer = new Timer((_) =>
|
_timer = new Timer((_) =>
|
||||||
{
|
{
|
||||||
ScanFilesAsync(path).Wait();
|
ScanFilesAsync(path).Wait();
|
||||||
}, null, TimeSpan.FromMinutes(1), TimeSpan.FromHours(1));
|
}, null, TimeSpan.FromMinutes(0), TimeSpan.FromHours(1));
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@ public class FileScannerService(MediaService mediaService, IConfiguration config
|
|||||||
|
|
||||||
private async Task ScanFilesAsync(string path)
|
private async Task ScanFilesAsync(string path)
|
||||||
{
|
{
|
||||||
|
logger.LogInformation("Scanning Files");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
|
var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
|
||||||
@@ -41,11 +42,22 @@ public class FileScannerService(MediaService mediaService, IConfiguration config
|
|||||||
foreach (var filePath in files)
|
foreach (var filePath in files)
|
||||||
{
|
{
|
||||||
var relativePath = Path.GetRelativePath(path, filePath);
|
var relativePath = Path.GetRelativePath(path, filePath);
|
||||||
|
if (relativePath[0] == '.') //Ignore hidden folders
|
||||||
|
continue;
|
||||||
if (existingFiles.Contains(relativePath))
|
if (existingFiles.Contains(relativePath))
|
||||||
continue;
|
continue;
|
||||||
entries.Add(MediaEntry.Parse(relativePath));
|
var entry = MediaEntry.Parse(relativePath);
|
||||||
|
if(entry.HasError)
|
||||||
|
{
|
||||||
|
logger.LogError(entry.Error.GetException(), "Failed to parse file data");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
entries.Add(entry);
|
||||||
|
}
|
||||||
|
if(entries.Count > 0) {
|
||||||
await mediaService.AddMediaBulkAsync(entries);
|
await mediaService.AddMediaBulkAsync(entries);
|
||||||
|
logger.LogInformation("Added {count} file entries", entries.Count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,16 +1,47 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
use crate::components::playback::{Timeline, Viewport};
|
use crate::{
|
||||||
|
components::playback::{Timeline, Viewport},
|
||||||
|
rpc::{
|
||||||
|
azki::{MediaRangeRequest, MediaType},
|
||||||
|
get_rpc_client,
|
||||||
|
},
|
||||||
|
};
|
||||||
const PLAYER_CSS: Asset = asset!("/assets/styling/player.scss");
|
const PLAYER_CSS: Asset = asset!("/assets/styling/player.scss");
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Player() -> Element {
|
pub fn Player() -> Element {
|
||||||
|
let entries = use_resource(|| async move {
|
||||||
|
let mut client = get_rpc_client();
|
||||||
|
let result = client
|
||||||
|
.get_media_entries_in_range(MediaRangeRequest {
|
||||||
|
r#type: MediaType::Video.into(),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
if let Ok(entries) = result {
|
||||||
|
let res = entries.into_inner();
|
||||||
|
return Ok(res.entries);
|
||||||
|
} else {
|
||||||
|
let err = result.err().unwrap();
|
||||||
|
let msg = err.message();
|
||||||
|
return Err(format!("Failed to load results: {msg}"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let len = match entries.cloned() {
|
||||||
|
Some(value) => match value {
|
||||||
|
Ok(result) => result.len().to_string(),
|
||||||
|
Err(err) => err,
|
||||||
|
},
|
||||||
|
_ => "Not Loaded".to_string(),
|
||||||
|
};
|
||||||
rsx! {
|
rsx! {
|
||||||
document::Link { rel: "stylesheet", href: PLAYER_CSS }
|
document::Link { rel: "stylesheet", href: PLAYER_CSS }
|
||||||
div{
|
div{
|
||||||
id: "player",
|
id: "player",
|
||||||
div {
|
div {
|
||||||
id: "head"
|
id: "head",
|
||||||
|
"r {len}"
|
||||||
}
|
}
|
||||||
Viewport { }
|
Viewport { }
|
||||||
Timeline { }
|
Timeline { }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ mod rpc;
|
|||||||
mod views;
|
mod views;
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
pub const RPC_HOST: &'static str = "http://localhost:8081";
|
pub const RPC_HOST: &'static str = "http://localhost:5177";
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
pub const RPC_HOST: &'static str = "https://grpc.aoba.app:8443";
|
pub const RPC_HOST: &'static str = "https://grpc.aoba.app:8443";
|
||||||
|
|
||||||
|
|||||||
@@ -47,3 +47,15 @@ impl Interceptor for AuthInterceptor {
|
|||||||
return Ok(request);
|
return Ok(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_rpc_client() -> AzKiClient<InterceptedService<Client, AuthInterceptor>> {
|
||||||
|
return RPC_CLIENT.get_client();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn login(jwt: String) {
|
||||||
|
*RPC_CLIENT.jwt.write().unwrap() = Some(jwt);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn logout() {
|
||||||
|
*RPC_CLIENT.jwt.write().unwrap() = None;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user