diff --git a/.gitignore b/.gitignore index 2e5f40f53..756e09822 100644 --- a/.gitignore +++ b/.gitignore @@ -491,11 +491,11 @@ appsettings.json /API/kavita.db-wal /API/Hangfire.db /API/Hangfire-log.db -cache/ +API/cache/ /API/wwwroot/ /API/cache/ /API/temp/ _temp/ _output/ -stats/ +API/stats/ UI/Web/dist/ diff --git a/API/Controllers/ServerController.cs b/API/Controllers/ServerController.cs index b93a1178b..2fd460f79 100644 --- a/API/Controllers/ServerController.cs +++ b/API/Controllers/ServerController.cs @@ -1,10 +1,10 @@ using System; using System.IO; using System.Threading.Tasks; -using API.DTOs; +using API.DTOs.Stats; using API.Extensions; using API.Interfaces.Services; -using API.Services; +using API.Services.Tasks; using Kavita.Common; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; diff --git a/API/Controllers/StatsController.cs b/API/Controllers/StatsController.cs index f35552eec..d219db790 100644 --- a/API/Controllers/StatsController.cs +++ b/API/Controllers/StatsController.cs @@ -1,6 +1,6 @@ using System; using System.Threading.Tasks; -using API.DTOs; +using API.DTOs.Stats; using API.Interfaces.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; diff --git a/API/DTOs/ClientInfoDto.cs b/API/DTOs/Stats/ClientInfoDto.cs similarity index 66% rename from API/DTOs/ClientInfoDto.cs rename to API/DTOs/Stats/ClientInfoDto.cs index 7070e64d7..f2be3b41f 100644 --- a/API/DTOs/ClientInfoDto.cs +++ b/API/DTOs/Stats/ClientInfoDto.cs @@ -1,6 +1,6 @@ using System; -namespace API.DTOs +namespace API.DTOs.Stats { public class ClientInfoDto { @@ -16,13 +16,14 @@ namespace API.DTOs public DetailsVersion Os { get; set; } public DateTime? CollectedAt { get; set; } + public bool UsingDarkTheme { get; set; } public bool IsTheSameDevice(ClientInfoDto clientInfoDto) { - return (clientInfoDto.ScreenResolution ?? "").Equals(ScreenResolution) && - (clientInfoDto.PlatformType ?? "").Equals(PlatformType) && - (clientInfoDto.Browser?.Name ?? "").Equals(Browser?.Name) && - (clientInfoDto.Os?.Name ?? "").Equals(Os?.Name) && + return (clientInfoDto.ScreenResolution ?? string.Empty).Equals(ScreenResolution) && + (clientInfoDto.PlatformType ?? string.Empty).Equals(PlatformType) && + (clientInfoDto.Browser?.Name ?? string.Empty).Equals(Browser?.Name) && + (clientInfoDto.Os?.Name ?? string.Empty).Equals(Os?.Name) && clientInfoDto.CollectedAt.GetValueOrDefault().ToString("yyyy-MM-dd") .Equals(CollectedAt.GetValueOrDefault().ToString("yyyy-MM-dd")); } @@ -33,4 +34,4 @@ namespace API.DTOs public string Name { get; set; } public string Version { get; set; } } -} \ No newline at end of file +} diff --git a/API/DTOs/ServerInfoDto.cs b/API/DTOs/Stats/ServerInfoDto.cs similarity index 73% rename from API/DTOs/ServerInfoDto.cs rename to API/DTOs/Stats/ServerInfoDto.cs index 0f4a86d64..2aecebecc 100644 --- a/API/DTOs/ServerInfoDto.cs +++ b/API/DTOs/Stats/ServerInfoDto.cs @@ -1,4 +1,4 @@ -namespace API.DTOs +namespace API.DTOs.Stats { public class ServerInfoDto { @@ -8,5 +8,7 @@ public string KavitaVersion { get; set; } public string BuildBranch { get; set; } public string Culture { get; set; } + public bool IsDocker { get; set; } + public int NumOfCores { get; set; } } -} \ No newline at end of file +} diff --git a/API/DTOs/UsageInfoDto.cs b/API/DTOs/Stats/UsageInfoDto.cs similarity index 95% rename from API/DTOs/UsageInfoDto.cs rename to API/DTOs/Stats/UsageInfoDto.cs index ba4b06b41..64aaeefee 100644 --- a/API/DTOs/UsageInfoDto.cs +++ b/API/DTOs/Stats/UsageInfoDto.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using API.Entities.Enums; -namespace API.DTOs +namespace API.DTOs.Stats { public class UsageInfoDto { @@ -21,4 +21,4 @@ namespace API.DTOs public LibraryType Type { get; set; } public int Count { get; set; } } -} \ No newline at end of file +} diff --git a/API/DTOs/UsageStatisticsDto.cs b/API/DTOs/Stats/UsageStatisticsDto.cs similarity index 96% rename from API/DTOs/UsageStatisticsDto.cs rename to API/DTOs/Stats/UsageStatisticsDto.cs index 1180401c3..08e15dc3b 100644 --- a/API/DTOs/UsageStatisticsDto.cs +++ b/API/DTOs/Stats/UsageStatisticsDto.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; -namespace API.DTOs +namespace API.DTOs.Stats { public class UsageStatisticsDto { @@ -30,4 +30,4 @@ namespace API.DTOs ClientsInfo.Add(clientInfoDto); } } -} \ No newline at end of file +} diff --git a/API/Interfaces/Services/IStatsService.cs b/API/Interfaces/Services/IStatsService.cs index f91a4e522..f30222385 100644 --- a/API/Interfaces/Services/IStatsService.cs +++ b/API/Interfaces/Services/IStatsService.cs @@ -1,5 +1,5 @@ using System.Threading.Tasks; -using API.DTOs; +using API.DTOs.Stats; namespace API.Interfaces.Services { @@ -10,4 +10,4 @@ namespace API.Interfaces.Services Task CollectRelevantData(); Task CollectAndSendStatsData(); } -} \ No newline at end of file +} diff --git a/API/Services/Clients/StatsApiClient.cs b/API/Services/Clients/StatsApiClient.cs index 478852db5..e6845178d 100644 --- a/API/Services/Clients/StatsApiClient.cs +++ b/API/Services/Clients/StatsApiClient.cs @@ -2,7 +2,7 @@ using System.Net.Http; using System.Net.Http.Json; using System.Threading.Tasks; -using API.DTOs; +using API.DTOs.Stats; using Microsoft.Extensions.Logging; namespace API.Services.Clients diff --git a/API/Services/StatsService.cs b/API/Services/Tasks/StatsService.cs similarity index 96% rename from API/Services/StatsService.cs rename to API/Services/Tasks/StatsService.cs index 0e4748845..fc5e7b256 100644 --- a/API/Services/StatsService.cs +++ b/API/Services/Tasks/StatsService.cs @@ -6,7 +6,7 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; using API.Data; -using API.DTOs; +using API.DTOs.Stats; using API.Interfaces; using API.Interfaces.Services; using API.Services.Clients; @@ -15,7 +15,7 @@ using Kavita.Common.EnvironmentInfo; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -namespace API.Services +namespace API.Services.Tasks { public class StatsService : IStatsService { @@ -142,7 +142,9 @@ namespace API.Services RunTimeVersion = RuntimeInformation.FrameworkDescription, KavitaVersion = BuildInfo.Version.ToString(), Culture = Thread.CurrentThread.CurrentCulture.Name, - BuildBranch = BuildInfo.Branch + BuildBranch = BuildInfo.Branch, + IsDocker = new OsInfo(Array.Empty()).IsDocker, + NumOfCores = Environment.ProcessorCount }; return serverInfo; diff --git a/API/Startup.cs b/API/Startup.cs index e443ae5d8..fea6d0603 100644 --- a/API/Startup.cs +++ b/API/Startup.cs @@ -7,6 +7,7 @@ using API.Services; using API.Services.HostedServices; using Hangfire; using Hangfire.MemoryStorage; +using Kavita.Common; using Kavita.Common.EnvironmentInfo; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; diff --git a/UI/Web/src/app/_interceptors/error.interceptor.ts b/UI/Web/src/app/_interceptors/error.interceptor.ts index 9f8645a39..20c48fd8a 100644 --- a/UI/Web/src/app/_interceptors/error.interceptor.ts +++ b/UI/Web/src/app/_interceptors/error.interceptor.ts @@ -25,10 +25,6 @@ export class ErrorInterceptor implements HttpInterceptor { if (error === undefined || error === null) { return throwError(error); } - - if (!environment.production) { - console.error('error:', error); - } switch (error.status) { case 400: @@ -99,12 +95,15 @@ export class ErrorInterceptor implements HttpInterceptor { } private handleServerException(error: any) { - console.error('500 error:', error); const err = error.error; if (err.hasOwnProperty('message') && err.message.trim() !== '') { + if (err.message != 'User is not authenticated') { + console.log('500 error: ', error); + } this.toastr.error(err.message); } else { this.toastr.error('There was an unknown critical error.'); + console.error('500 error:', error); } } diff --git a/UI/Web/src/app/_models/client-info.ts b/UI/Web/src/app/_models/stats/client-info.ts similarity index 89% rename from UI/Web/src/app/_models/client-info.ts rename to UI/Web/src/app/_models/stats/client-info.ts index c4a5cd6b1..67916b8cf 100644 --- a/UI/Web/src/app/_models/client-info.ts +++ b/UI/Web/src/app/_models/stats/client-info.ts @@ -7,6 +7,7 @@ export interface ClientInfo { platformType: string, kavitaUiVersion: string, screenResolution: string; + usingDarkTheme: boolean; collectedAt?: Date; } diff --git a/UI/Web/src/app/_models/details-version.ts b/UI/Web/src/app/_models/stats/details-version.ts similarity index 100% rename from UI/Web/src/app/_models/details-version.ts rename to UI/Web/src/app/_models/stats/details-version.ts diff --git a/UI/Web/src/app/_services/stats.service.ts b/UI/Web/src/app/_services/stats.service.ts index 56d56d633..1c9d19133 100644 --- a/UI/Web/src/app/_services/stats.service.ts +++ b/UI/Web/src/app/_services/stats.service.ts @@ -1,7 +1,13 @@ import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; +import * as Bowser from "bowser"; +import { take } from "rxjs/operators"; import { environment } from "src/environments/environment"; -import { ClientInfo } from "../_models/client-info"; +import { ClientInfo } from "../_models/stats/client-info"; +import { DetailsVersion } from "../_models/stats/details-version"; +import { NavService } from "./nav.service"; +import { version } from '../../../package.json'; + @Injectable({ providedIn: 'root' @@ -10,9 +16,27 @@ export class StatsService { baseUrl = environment.apiUrl; - constructor(private httpClient: HttpClient) { } + constructor(private httpClient: HttpClient, private navService: NavService) { } - public sendClientInfo(clientInfo: ClientInfo) { - return this.httpClient.post(this.baseUrl + 'stats/client-info', clientInfo); + public async sendClientInfo() { + const data = await this.getInfo(); + this.httpClient.post(this.baseUrl + 'stats/client-info', data); + } + + private async getInfo(): Promise { + const screenResolution = `${window.screen.width} x ${window.screen.height}`; + + const browser = Bowser.getParser(window.navigator.userAgent); + + const usingDarkTheme = await this.navService.darkMode$.pipe(take(1)).toPromise(); + + return { + os: browser.getOS() as DetailsVersion, + browser: browser.getBrowser() as DetailsVersion, + platformType: browser.getPlatformType(), + kavitaUiVersion: version, + screenResolution, + usingDarkTheme + }; } } \ No newline at end of file diff --git a/UI/Web/src/app/home/home.component.ts b/UI/Web/src/app/home/home.component.ts index 4de69832b..a33a7358e 100644 --- a/UI/Web/src/app/home/home.component.ts +++ b/UI/Web/src/app/home/home.component.ts @@ -5,7 +5,6 @@ import { take } from 'rxjs/operators'; import { MemberService } from '../_services/member.service'; import { AccountService } from '../_services/account.service'; import { StatsService } from '../_services/stats.service'; -import * as ClientUtils from "../shared/utils/clientUtils"; @Component({ selector: 'app-home', @@ -35,9 +34,7 @@ export class HomeComponent implements OnInit { this.accountService.currentUser$.pipe(take(1)).subscribe(user => { - this.statsService.sendClientInfo(ClientUtils.getClientInfo()) - .pipe(take(1)) - .subscribe(resp => {/* No Operation */}); + this.statsService.sendClientInfo(); if (user) { this.router.navigateByUrl('/library'); diff --git a/UI/Web/src/app/series-detail/series-detail.component.scss b/UI/Web/src/app/series-detail/series-detail.component.scss index d154833cf..a20fa48be 100644 --- a/UI/Web/src/app/series-detail/series-detail.component.scss +++ b/UI/Web/src/app/series-detail/series-detail.component.scss @@ -8,6 +8,7 @@ .poster { width: 100%; + max-height: 230px; } .rating-star { diff --git a/UI/Web/src/app/shared/utils/clientUtils.ts b/UI/Web/src/app/shared/utils/clientUtils.ts deleted file mode 100644 index 7170df442..000000000 --- a/UI/Web/src/app/shared/utils/clientUtils.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as Bowser from "bowser"; -import { version } from '../../../../package.json'; -import { ClientInfo } from "src/app/_models/client-info"; -import { DetailsVersion } from "src/app/_models/details-version"; - -const getClientInfo = (): ClientInfo => { - - const screenResolution = `${window.screen.width} x ${window.screen.height}`; - - const browser = Bowser.getParser(window.navigator.userAgent); - - return { - os: browser.getOS() as DetailsVersion, - browser: browser.getBrowser() as DetailsVersion, - platformType: browser.getPlatformType(), - kavitaUiVersion: version, - screenResolution - }; -} - -export { getClientInfo }; \ No newline at end of file