From 68593d86c894b2db9a71aec5e998cc24279a82aa Mon Sep 17 00:00:00 2001 From: zexuz Date: Mon, 22 Apr 2019 19:46:35 +0200 Subject: [PATCH] Fixed sessions --- Mpv.JsonIpc/Api.cs | 14 + SnackTime.Core/DependencyModule.cs | 15 +- SnackTime.Core/LocalSessionRepo.cs | 36 + .../Media/Episodes/EpisodeBuilder.cs | 21 +- .../Media/Episodes/EpisodeProvider.cs | 4 +- SnackTime.Core/Session/ISessionRepo.cs | 19 + SnackTime.Core/Session/ISessionRepoFactory.cs | 11 + .../{SessionService.cs => SessionFactory.cs} | 33 +- SnackTime.Core/Settings/SettingsService.cs | 16 +- .../csharp-grpc/File-serviceGrpc.cs | 10 +- .../csharp/FileDownload.cs | 21 +- .../csharp/FileService.cs | 12 +- .../csharp/Settings.cs | 373 ++++- .../proto/file-service/file-download.proto | 2 +- .../proto/file-service/file-service.proto | 2 +- .../proto/settings.proto | 11 +- .../proto/status-service/status-ping.proto | 11 + .../proto/status-service/status-service.proto | 13 + SnackTime.MediaServer/DependencyModule.cs | 14 +- SnackTime.MediaServer/SessionController.cs | 20 +- SnackTime.MediaServer/SessionRepoFactory.cs | 20 + SnackTime.MediaServer/StatusController.cs | 15 + .../Controllers/EpisodeController.cs | 1 + .../Controllers/HistoryController.cs | 14 +- .../Controllers/SeriesController.cs | 1 + .../Controllers/SessionController.cs | 11 +- SnackTime.WebApi/DependencyModule.cs | 61 +- SnackTime.WebApi/MediaPlayerObserver.cs | 27 +- .../Services/FileDownloadService.cs | 6 +- .../Services/GrpcClientProvider.cs | 63 + .../Services/RemoteSessionRepo.cs | 33 + .../Services/SessionRepoFactory.cs | 29 + .../Services/SessionSyncService.cs | 46 +- SnackTime.WebApi/Services/StatusService.cs | 48 + app/src/logic/api/protogen/types.d.ts | 462 +++--- app/src/logic/api/protogen/types.js | 1253 ++++++++++------- app/src/views/Settings.vue | 48 +- 37 files changed, 1887 insertions(+), 909 deletions(-) create mode 100644 SnackTime.Core/LocalSessionRepo.cs create mode 100644 SnackTime.Core/Session/ISessionRepo.cs create mode 100644 SnackTime.Core/Session/ISessionRepoFactory.cs rename SnackTime.Core/Session/{SessionService.cs => SessionFactory.cs} (52%) create mode 100644 SnackTime.MediaServer.Proto/proto/status-service/status-ping.proto create mode 100644 SnackTime.MediaServer.Proto/proto/status-service/status-service.proto create mode 100644 SnackTime.MediaServer/SessionRepoFactory.cs create mode 100644 SnackTime.MediaServer/StatusController.cs create mode 100644 SnackTime.WebApi/Services/GrpcClientProvider.cs create mode 100644 SnackTime.WebApi/Services/RemoteSessionRepo.cs create mode 100644 SnackTime.WebApi/Services/SessionRepoFactory.cs create mode 100644 SnackTime.WebApi/Services/StatusService.cs diff --git a/Mpv.JsonIpc/Api.cs b/Mpv.JsonIpc/Api.cs index 169424e..4ab0ff7 100644 --- a/Mpv.JsonIpc/Api.cs +++ b/Mpv.JsonIpc/Api.cs @@ -40,6 +40,20 @@ public async Task GetCurrentPosition() public async Task GetDuration() { var result = await _ipc.GetProperty(Property.Duration); + + int counter = 0; + while (Math.Abs(result.Data) < 1) + { + await Task.Delay(100); + result = await _ipc.GetProperty(Property.Duration); + + counter++; + if (counter > 20) + { + break; + } + } + return TimeSpan.FromSeconds(result.Data); } } diff --git a/SnackTime.Core/DependencyModule.cs b/SnackTime.Core/DependencyModule.cs index 086a37d..880c7ae 100644 --- a/SnackTime.Core/DependencyModule.cs +++ b/SnackTime.Core/DependencyModule.cs @@ -18,9 +18,11 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); + + builder.RegisterType().As(); builder.RegisterType().AsSelf(); - builder.RegisterType().AsSelf(); + builder.RegisterType().AsSelf(); builder.RegisterType>().AsSelf().SingleInstance(); builder.RegisterType().AsSelf(); @@ -29,13 +31,6 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); } - - public class SonarrConfig - { - public string Host { get; set; } - public int Port { get; set; } - public string ApiKey { get; set; } - } } public class SonarrFactory @@ -55,9 +50,9 @@ public SonarrClient GetClient() var settings = _settingsService.Get(); - if (!string.IsNullOrWhiteSpace(settings.MediaServerAddress)) + if (!string.IsNullOrWhiteSpace(settings.Remote.MediaServerAddress)) { - host = settings.MediaServerAddress; + host = settings.Remote.MediaServerAddress; } diff --git a/SnackTime.Core/LocalSessionRepo.cs b/SnackTime.Core/LocalSessionRepo.cs new file mode 100644 index 0000000..dab5293 --- /dev/null +++ b/SnackTime.Core/LocalSessionRepo.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using SnackTime.Core.Database; +using SnackTime.Core.Session; + +namespace SnackTime.Core +{ + public class LocalSessionRepo : ILocalSessionRepo, IRemoteSessionRepo + { + private readonly DatabaseFactory _databaseFactory; + + public LocalSessionRepo(DatabaseFactory databaseFactory) + { + _databaseFactory = databaseFactory; + } + + public Task UpsertSession(MediaServer.Storage.ProtoGenerated.Session session) + { + using (var db = _databaseFactory.GetRepository()) + { + db.Upsert(session); + } + + return Task.CompletedTask; + } + + public Task> GetAll() + { + using (var db = _databaseFactory.GetRepository()) + { + var sessions = db.Fetch(); + return Task.FromResult(sessions); + } + } + } +} \ No newline at end of file diff --git a/SnackTime.Core/Media/Episodes/EpisodeBuilder.cs b/SnackTime.Core/Media/Episodes/EpisodeBuilder.cs index c70a624..1c269c5 100644 --- a/SnackTime.Core/Media/Episodes/EpisodeBuilder.cs +++ b/SnackTime.Core/Media/Episodes/EpisodeBuilder.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using SnackTime.Core.Session; using SnackTime.MediaServer.Models.ProtoGenerated; using SnackTime.MediaServer.Storage.ProtoGenerated; @@ -8,21 +9,24 @@ namespace SnackTime.Core.Media.Episodes { public class EpisodeBuilder { - private readonly SessionService _sessionService; + private readonly ISessionRepoFactory _sessionRepoFactory; - public EpisodeBuilder(SessionService sessionService) + public EpisodeBuilder(ISessionRepoFactory sessionRepoFactory) { - _sessionService = sessionService; + _sessionRepoFactory = sessionRepoFactory; } - public List Build(IEnumerable episodes) + public async Task> Build(IEnumerable episodes) { - return episodes.Select(Build) + var tasks = episodes.Select(Build).ToList(); + await Task.WhenAll(tasks); + + return tasks.Select(task => task.Result) .OrderByDescending(episode => episode.SeasonNumber) .ToList(); } - public Episode Build(SonarrSharp.Models.Episode episode) + public async Task Build(SonarrSharp.Models.Episode episode) { var mediaFileId = new MediaFileId { @@ -30,12 +34,13 @@ public Episode Build(SonarrSharp.Models.Episode episode) MediaId = episode.SeriesId, FileId = episode.EpisodeFileId, }; + var sessionRepo = await _sessionRepoFactory.GetRepo(); - var allSessionsForCurrentEpisode = _sessionService.GetAll() + var allSessionsForCurrentEpisode = (await sessionRepo.GetAll()) .Where(session => session.MediaId == mediaFileId.ToString()) .ToList(); - var lastSession = allSessionsForCurrentEpisode.OrderBy(session => session.EndUTC).FirstOrDefault(); + var lastSession = allSessionsForCurrentEpisode.OrderByDescending(session => session.EndUTC).FirstOrDefault(); return new Episode { diff --git a/SnackTime.Core/Media/Episodes/EpisodeProvider.cs b/SnackTime.Core/Media/Episodes/EpisodeProvider.cs index 04dc0e3..876d1b8 100644 --- a/SnackTime.Core/Media/Episodes/EpisodeProvider.cs +++ b/SnackTime.Core/Media/Episodes/EpisodeProvider.cs @@ -19,13 +19,13 @@ public EpisodeProvider(SonarrFactory sonarrFactory, EpisodeBuilder episodeBuilde public async Task> GetEpisodesForSeriesById(int seriesId) { var episodes = await _client.Episode.GetEpisodes(seriesId); - return _seriesBuilder.Build(episodes); + return await _seriesBuilder.Build(episodes); } public async Task GetEpisodeById(int id) { var episodes = await _client.Episode.GetEpisode(id); - return _seriesBuilder.Build(episodes); + return await _seriesBuilder.Build(episodes); } } } \ No newline at end of file diff --git a/SnackTime.Core/Session/ISessionRepo.cs b/SnackTime.Core/Session/ISessionRepo.cs new file mode 100644 index 0000000..b5c759a --- /dev/null +++ b/SnackTime.Core/Session/ISessionRepo.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace SnackTime.Core.Session +{ + public interface ISessionRepo + { + Task UpsertSession(MediaServer.Storage.ProtoGenerated.Session session); + Task> GetAll(); + } + + public interface ILocalSessionRepo : ISessionRepo + { + } + + public interface IRemoteSessionRepo : ISessionRepo + { + } +} \ No newline at end of file diff --git a/SnackTime.Core/Session/ISessionRepoFactory.cs b/SnackTime.Core/Session/ISessionRepoFactory.cs new file mode 100644 index 0000000..097d784 --- /dev/null +++ b/SnackTime.Core/Session/ISessionRepoFactory.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace SnackTime.Core.Session +{ + public interface ISessionRepoFactory + { + Task GetRepo(); + } + + +} \ No newline at end of file diff --git a/SnackTime.Core/Session/SessionService.cs b/SnackTime.Core/Session/SessionFactory.cs similarity index 52% rename from SnackTime.Core/Session/SessionService.cs rename to SnackTime.Core/Session/SessionFactory.cs index e82fb09..98251bf 100644 --- a/SnackTime.Core/Session/SessionService.cs +++ b/SnackTime.Core/Session/SessionFactory.cs @@ -1,18 +1,17 @@ using System; -using System.Collections.Generic; +using System.Linq; using SnackTime.Core.Database; +using SnackTime.MediaServer.Service.Session; using SnackTime.MediaServer.Storage.ProtoGenerated; namespace SnackTime.Core.Session { - public class SessionService + public class SessionFactory { - private readonly DatabaseFactory _databaseFactory; - private readonly TimeService _timeService; + private readonly TimeService _timeService; - public SessionService(DatabaseFactory databaseFactory, TimeService timeService) + public SessionFactory(TimeService timeService) { - _databaseFactory = databaseFactory; _timeService = timeService; } @@ -30,32 +29,16 @@ public MediaServer.Storage.ProtoGenerated.Session CreateNewSession timeWatched.EndPostionInSec = startPosition.Value.TotalSeconds; } - var sessionId = Guid.NewGuid().ToString("N"); - return new MediaServer.Storage.ProtoGenerated.Session + var session = new MediaServer.Storage.ProtoGenerated.Session { - Id = sessionId, + Id = Guid.NewGuid().ToString("N"), MediaId = mediaFileId.ToString(), Duration = timeWatched, StartUTC = _timeService.GetCurrentTimeAsUnixSeconds(), EndUTC = _timeService.GetCurrentTimeAsUnixSeconds(), MediaLenghtInSec = mediaDuration.TotalSeconds, }; - } - - public void UpsertSession(MediaServer.Storage.ProtoGenerated.Session session) - { - using (var db = _databaseFactory.GetRepository()) - { - db.Upsert(session); - } - } - - public IList GetAll() - { - using (var db = _databaseFactory.GetRepository()) - { - return db.Fetch(); - } + return session; } } } \ No newline at end of file diff --git a/SnackTime.Core/Settings/SettingsService.cs b/SnackTime.Core/Settings/SettingsService.cs index 875028c..1b313f8 100644 --- a/SnackTime.Core/Settings/SettingsService.cs +++ b/SnackTime.Core/Settings/SettingsService.cs @@ -1,4 +1,6 @@ using Microsoft.Extensions.Logging; +using SnackTime.App.Settings.ProtoGenerated; +using SonarrSharp.Models; namespace SnackTime.Core.Settings { @@ -25,7 +27,19 @@ public void Save(App.Settings.ProtoGenerated.Settings settings) public App.Settings.ProtoGenerated.Settings Get() { - return _settingsRepo.Get()?.Value ?? new App.Settings.ProtoGenerated.Settings(); + var setting = _settingsRepo.Get()?.Value ?? new App.Settings.ProtoGenerated.Settings(); + + if (setting.Remote == null) + { + setting.Remote = new Remote(); + } + + if (setting.System == null) + { + setting.System = new LocalSystem(); + } + + return setting; } } } \ No newline at end of file diff --git a/SnackTime.MediaServer.Proto/csharp-grpc/File-serviceGrpc.cs b/SnackTime.MediaServer.Proto/csharp-grpc/File-serviceGrpc.cs index 51fac21..247b4e1 100644 --- a/SnackTime.MediaServer.Proto/csharp-grpc/File-serviceGrpc.cs +++ b/SnackTime.MediaServer.Proto/csharp-grpc/File-serviceGrpc.cs @@ -10,17 +10,17 @@ namespace SnackTime.MediaServer.Service.File { public static partial class File { - static readonly string __ServiceName = "snacktime.series.file.File"; + static readonly string __ServiceName = "snacktime.file.service.File"; - static readonly grpc::Marshaller __Marshaller_snacktime_series_file_DownloadFileRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::SnackTime.MediaServer.Service.File.DownloadFileRequest.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_snacktime_series_file_ResponseDownloadFile = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::SnackTime.MediaServer.Service.File.ResponseDownloadFile.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_snacktime_file_service_DownloadFileRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::SnackTime.MediaServer.Service.File.DownloadFileRequest.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_snacktime_file_service_ResponseDownloadFile = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::SnackTime.MediaServer.Service.File.ResponseDownloadFile.Parser.ParseFrom); static readonly grpc::Method __Method_Download = new grpc::Method( grpc::MethodType.ServerStreaming, __ServiceName, "Download", - __Marshaller_snacktime_series_file_DownloadFileRequest, - __Marshaller_snacktime_series_file_ResponseDownloadFile); + __Marshaller_snacktime_file_service_DownloadFileRequest, + __Marshaller_snacktime_file_service_ResponseDownloadFile); /// Service descriptor public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor diff --git a/SnackTime.MediaServer.Proto/csharp/FileDownload.cs b/SnackTime.MediaServer.Proto/csharp/FileDownload.cs index f8383ac..4bdc9fb 100644 --- a/SnackTime.MediaServer.Proto/csharp/FileDownload.cs +++ b/SnackTime.MediaServer.Proto/csharp/FileDownload.cs @@ -24,16 +24,17 @@ public static partial class FileDownloadReflection { static FileDownloadReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "CiZwcm90by9maWxlLXNlcnZpY2UvZmlsZS1kb3dubG9hZC5wcm90bxIVc25h", - "Y2t0aW1lLnNlcmllcy5maWxlIioKE0Rvd25sb2FkRmlsZVJlcXVlc3QSEwoL", - "bWVkaWFGaWxlSWQYASABKAkisAEKFFJlc3BvbnNlRG93bmxvYWRGaWxlEjEK", - "B3N0YXJ0ZWQYASABKAsyHi5zbmFja3RpbWUuc2VyaWVzLmZpbGUuU3RhcnRl", - "ZEgAEjAKCHByb2dyZXNzGAIgASgLMhwuc25hY2t0aW1lLnNlcmllcy5maWxl", - "LkNodW5rSAASKwoEZG9uZRgDIAEoCzIbLnNuYWNrdGltZS5zZXJpZXMuZmls", - "ZS5Eb25lSABCBgoEdHlwZSJBCgdTdGFydGVkEg4KBmxlbmdodBgBIAEoARIU", - "CgxzaXplUGVyQ2h1bmsYAiABKAUSEAoIRmlsZU5hbWUYAyABKAkiGAoFQ2h1", - "bmsSDwoHQ29udGVudBgBIAEoDCIUCgREb25lEgwKBEhhc2gYASABKAlCJaoC", - "IlNuYWNrVGltZS5NZWRpYVNlcnZlci5TZXJ2aWNlLkZpbGViBnByb3RvMw==")); + "CiZwcm90by9maWxlLXNlcnZpY2UvZmlsZS1kb3dubG9hZC5wcm90bxIWc25h", + "Y2t0aW1lLmZpbGUuc2VydmljZSIqChNEb3dubG9hZEZpbGVSZXF1ZXN0EhMK", + "C21lZGlhRmlsZUlkGAEgASgJIrMBChRSZXNwb25zZURvd25sb2FkRmlsZRIy", + "CgdzdGFydGVkGAEgASgLMh8uc25hY2t0aW1lLmZpbGUuc2VydmljZS5TdGFy", + "dGVkSAASMQoIcHJvZ3Jlc3MYAiABKAsyHS5zbmFja3RpbWUuZmlsZS5zZXJ2", + "aWNlLkNodW5rSAASLAoEZG9uZRgDIAEoCzIcLnNuYWNrdGltZS5maWxlLnNl", + "cnZpY2UuRG9uZUgAQgYKBHR5cGUiQQoHU3RhcnRlZBIOCgZsZW5naHQYASAB", + "KAESFAoMc2l6ZVBlckNodW5rGAIgASgFEhAKCEZpbGVOYW1lGAMgASgJIhgK", + "BUNodW5rEg8KB0NvbnRlbnQYASABKAwiFAoERG9uZRIMCgRIYXNoGAEgASgJ", + "QiWqAiJTbmFja1RpbWUuTWVkaWFTZXJ2ZXIuU2VydmljZS5GaWxlYgZwcm90", + "bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { diff --git a/SnackTime.MediaServer.Proto/csharp/FileService.cs b/SnackTime.MediaServer.Proto/csharp/FileService.cs index e5f2e29..96114b0 100644 --- a/SnackTime.MediaServer.Proto/csharp/FileService.cs +++ b/SnackTime.MediaServer.Proto/csharp/FileService.cs @@ -24,12 +24,12 @@ public static partial class FileServiceReflection { static FileServiceReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "CiVwcm90by9maWxlLXNlcnZpY2UvZmlsZS1zZXJ2aWNlLnByb3RvEhVzbmFj", - "a3RpbWUuc2VyaWVzLmZpbGUaJnByb3RvL2ZpbGUtc2VydmljZS9maWxlLWRv", - "d25sb2FkLnByb3RvMm8KBEZpbGUSZwoIRG93bmxvYWQSKi5zbmFja3RpbWUu", - "c2VyaWVzLmZpbGUuRG93bmxvYWRGaWxlUmVxdWVzdBorLnNuYWNrdGltZS5z", - "ZXJpZXMuZmlsZS5SZXNwb25zZURvd25sb2FkRmlsZSIAMAFCJaoCIlNuYWNr", - "VGltZS5NZWRpYVNlcnZlci5TZXJ2aWNlLkZpbGViBnByb3RvMw==")); + "CiVwcm90by9maWxlLXNlcnZpY2UvZmlsZS1zZXJ2aWNlLnByb3RvEhZzbmFj", + "a3RpbWUuZmlsZS5zZXJ2aWNlGiZwcm90by9maWxlLXNlcnZpY2UvZmlsZS1k", + "b3dubG9hZC5wcm90bzJxCgRGaWxlEmkKCERvd25sb2FkEisuc25hY2t0aW1l", + "LmZpbGUuc2VydmljZS5Eb3dubG9hZEZpbGVSZXF1ZXN0Giwuc25hY2t0aW1l", + "LmZpbGUuc2VydmljZS5SZXNwb25zZURvd25sb2FkRmlsZSIAMAFCJaoCIlNu", + "YWNrVGltZS5NZWRpYVNlcnZlci5TZXJ2aWNlLkZpbGViBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::SnackTime.MediaServer.Service.File.FileDownloadReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, null)); diff --git a/SnackTime.MediaServer.Proto/csharp/Settings.cs b/SnackTime.MediaServer.Proto/csharp/Settings.cs index 04c5479..b6ea4a5 100644 --- a/SnackTime.MediaServer.Proto/csharp/Settings.cs +++ b/SnackTime.MediaServer.Proto/csharp/Settings.cs @@ -25,14 +25,19 @@ static SettingsReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "ChRwcm90by9zZXR0aW5ncy5wcm90bxIWc25hY2t0aW1lLmFwcC5zZXR0aW5n", - "cyJuCghTZXR0aW5ncxIPCgdmaWxlRGlyGAEgASgJEhMKC3RlbXBGaWxlRGly", - "GAIgASgJEg8KB21wdlBhdGgYAyABKAkSDwoHc3ZwUGF0aBgEIAEoCRIaChJt", - "ZWRpYVNlcnZlckFkZHJlc3MYBSABKAlCKKoCJVNuYWNrVGltZS5BcHAuU2V0", - "dGluZ3MuUHJvdG9HZW5lcmF0ZWRiBnByb3RvMw==")); + "cyJvCghTZXR0aW5ncxIzCgZzeXN0ZW0YASABKAsyIy5zbmFja3RpbWUuYXBw", + "LnNldHRpbmdzLkxvY2FsU3lzdGVtEi4KBnJlbW90ZRgCIAEoCzIeLnNuYWNr", + "dGltZS5hcHAuc2V0dGluZ3MuUmVtb3RlIlUKC0xvY2FsU3lzdGVtEg8KB2Zp", + "bGVEaXIYASABKAkSEwoLdGVtcEZpbGVEaXIYAiABKAkSDwoHbXB2UGF0aBgD", + "IAEoCRIPCgdzdnBQYXRoGAQgASgJIjYKBlJlbW90ZRIaChJtZWRpYVNlcnZl", + "ckFkZHJlc3MYASABKAkSEAoIaXNPbmxpbmUYAiABKAhCKKoCJVNuYWNrVGlt", + "ZS5BcHAuU2V0dGluZ3MuUHJvdG9HZW5lcmF0ZWRiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::SnackTime.App.Settings.ProtoGenerated.Settings), global::SnackTime.App.Settings.ProtoGenerated.Settings.Parser, new[]{ "FileDir", "TempFileDir", "MpvPath", "SvpPath", "MediaServerAddress" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::SnackTime.App.Settings.ProtoGenerated.Settings), global::SnackTime.App.Settings.ProtoGenerated.Settings.Parser, new[]{ "System", "Remote" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::SnackTime.App.Settings.ProtoGenerated.LocalSystem), global::SnackTime.App.Settings.ProtoGenerated.LocalSystem.Parser, new[]{ "FileDir", "TempFileDir", "MpvPath", "SvpPath" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::SnackTime.App.Settings.ProtoGenerated.Remote), global::SnackTime.App.Settings.ProtoGenerated.Remote.Parser, new[]{ "MediaServerAddress", "IsOnline" }, null, null, null) })); } #endregion @@ -64,17 +69,185 @@ public Settings() { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Settings(Settings other) : this() { + system_ = other.system_ != null ? other.system_.Clone() : null; + remote_ = other.remote_ != null ? other.remote_.Clone() : null; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Settings Clone() { + return new Settings(this); + } + + /// Field number for the "system" field. + public const int SystemFieldNumber = 1; + private global::SnackTime.App.Settings.ProtoGenerated.LocalSystem system_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::SnackTime.App.Settings.ProtoGenerated.LocalSystem System { + get { return system_; } + set { + system_ = value; + } + } + + /// Field number for the "remote" field. + public const int RemoteFieldNumber = 2; + private global::SnackTime.App.Settings.ProtoGenerated.Remote remote_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::SnackTime.App.Settings.ProtoGenerated.Remote Remote { + get { return remote_; } + set { + remote_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Settings); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Settings other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (!object.Equals(System, other.System)) return false; + if (!object.Equals(Remote, other.Remote)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (system_ != null) hash ^= System.GetHashCode(); + if (remote_ != null) hash ^= Remote.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (system_ != null) { + output.WriteRawTag(10); + output.WriteMessage(System); + } + if (remote_ != null) { + output.WriteRawTag(18); + output.WriteMessage(Remote); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (system_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(System); + } + if (remote_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Remote); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Settings other) { + if (other == null) { + return; + } + if (other.system_ != null) { + if (system_ == null) { + system_ = new global::SnackTime.App.Settings.ProtoGenerated.LocalSystem(); + } + System.MergeFrom(other.System); + } + if (other.remote_ != null) { + if (remote_ == null) { + remote_ = new global::SnackTime.App.Settings.ProtoGenerated.Remote(); + } + Remote.MergeFrom(other.Remote); + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + if (system_ == null) { + system_ = new global::SnackTime.App.Settings.ProtoGenerated.LocalSystem(); + } + input.ReadMessage(system_); + break; + } + case 18: { + if (remote_ == null) { + remote_ = new global::SnackTime.App.Settings.ProtoGenerated.Remote(); + } + input.ReadMessage(remote_); + break; + } + } + } + } + + } + + public sealed partial class LocalSystem : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new LocalSystem()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::SnackTime.App.Settings.ProtoGenerated.SettingsReflection.Descriptor.MessageTypes[1]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public LocalSystem() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public LocalSystem(LocalSystem other) : this() { fileDir_ = other.fileDir_; tempFileDir_ = other.tempFileDir_; mpvPath_ = other.mpvPath_; svpPath_ = other.svpPath_; - mediaServerAddress_ = other.mediaServerAddress_; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Settings Clone() { - return new Settings(this); + public LocalSystem Clone() { + return new LocalSystem(this); } /// Field number for the "fileDir" field. @@ -121,24 +294,13 @@ public string SvpPath { } } - /// Field number for the "mediaServerAddress" field. - public const int MediaServerAddressFieldNumber = 5; - private string mediaServerAddress_ = ""; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public string MediaServerAddress { - get { return mediaServerAddress_; } - set { - mediaServerAddress_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); - } - } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { - return Equals(other as Settings); + return Equals(other as LocalSystem); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(Settings other) { + public bool Equals(LocalSystem other) { if (ReferenceEquals(other, null)) { return false; } @@ -149,7 +311,6 @@ public bool Equals(Settings other) { if (TempFileDir != other.TempFileDir) return false; if (MpvPath != other.MpvPath) return false; if (SvpPath != other.SvpPath) return false; - if (MediaServerAddress != other.MediaServerAddress) return false; return Equals(_unknownFields, other._unknownFields); } @@ -160,7 +321,6 @@ public override int GetHashCode() { if (TempFileDir.Length != 0) hash ^= TempFileDir.GetHashCode(); if (MpvPath.Length != 0) hash ^= MpvPath.GetHashCode(); if (SvpPath.Length != 0) hash ^= SvpPath.GetHashCode(); - if (MediaServerAddress.Length != 0) hash ^= MediaServerAddress.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -190,10 +350,6 @@ public void WriteTo(pb::CodedOutputStream output) { output.WriteRawTag(34); output.WriteString(SvpPath); } - if (MediaServerAddress.Length != 0) { - output.WriteRawTag(42); - output.WriteString(MediaServerAddress); - } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -214,9 +370,6 @@ public int CalculateSize() { if (SvpPath.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(SvpPath); } - if (MediaServerAddress.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(MediaServerAddress); - } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -224,7 +377,7 @@ public int CalculateSize() { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(Settings other) { + public void MergeFrom(LocalSystem other) { if (other == null) { return; } @@ -240,9 +393,6 @@ public void MergeFrom(Settings other) { if (other.SvpPath.Length != 0) { SvpPath = other.SvpPath; } - if (other.MediaServerAddress.Length != 0) { - MediaServerAddress = other.MediaServerAddress; - } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -270,10 +420,163 @@ public void MergeFrom(pb::CodedInputStream input) { SvpPath = input.ReadString(); break; } - case 42: { + } + } + } + + } + + public sealed partial class Remote : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Remote()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::SnackTime.App.Settings.ProtoGenerated.SettingsReflection.Descriptor.MessageTypes[2]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Remote() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Remote(Remote other) : this() { + mediaServerAddress_ = other.mediaServerAddress_; + isOnline_ = other.isOnline_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Remote Clone() { + return new Remote(this); + } + + /// Field number for the "mediaServerAddress" field. + public const int MediaServerAddressFieldNumber = 1; + private string mediaServerAddress_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string MediaServerAddress { + get { return mediaServerAddress_; } + set { + mediaServerAddress_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "isOnline" field. + public const int IsOnlineFieldNumber = 2; + private bool isOnline_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool IsOnline { + get { return isOnline_; } + set { + isOnline_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Remote); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Remote other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (MediaServerAddress != other.MediaServerAddress) return false; + if (IsOnline != other.IsOnline) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (MediaServerAddress.Length != 0) hash ^= MediaServerAddress.GetHashCode(); + if (IsOnline != false) hash ^= IsOnline.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (MediaServerAddress.Length != 0) { + output.WriteRawTag(10); + output.WriteString(MediaServerAddress); + } + if (IsOnline != false) { + output.WriteRawTag(16); + output.WriteBool(IsOnline); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (MediaServerAddress.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(MediaServerAddress); + } + if (IsOnline != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Remote other) { + if (other == null) { + return; + } + if (other.MediaServerAddress.Length != 0) { + MediaServerAddress = other.MediaServerAddress; + } + if (other.IsOnline != false) { + IsOnline = other.IsOnline; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { MediaServerAddress = input.ReadString(); break; } + case 16: { + IsOnline = input.ReadBool(); + break; + } } } } diff --git a/SnackTime.MediaServer.Proto/proto/file-service/file-download.proto b/SnackTime.MediaServer.Proto/proto/file-service/file-download.proto index 7dc4458..06ce6cc 100644 --- a/SnackTime.MediaServer.Proto/proto/file-service/file-download.proto +++ b/SnackTime.MediaServer.Proto/proto/file-service/file-download.proto @@ -2,7 +2,7 @@ syntax = "proto3"; option csharp_namespace = "SnackTime.MediaServer.Service.File"; -package snacktime.series.file; +package snacktime.file.service; message DownloadFileRequest { diff --git a/SnackTime.MediaServer.Proto/proto/file-service/file-service.proto b/SnackTime.MediaServer.Proto/proto/file-service/file-service.proto index 030251c..51d281b 100644 --- a/SnackTime.MediaServer.Proto/proto/file-service/file-service.proto +++ b/SnackTime.MediaServer.Proto/proto/file-service/file-service.proto @@ -4,7 +4,7 @@ option csharp_namespace = "SnackTime.MediaServer.Service.File"; import "proto/file-service/file-download.proto"; -package snacktime.series.file; +package snacktime.file.service; service File { rpc Download (DownloadFileRequest) returns (stream ResponseDownloadFile) { diff --git a/SnackTime.MediaServer.Proto/proto/settings.proto b/SnackTime.MediaServer.Proto/proto/settings.proto index 49bd1de..1d6bbb0 100644 --- a/SnackTime.MediaServer.Proto/proto/settings.proto +++ b/SnackTime.MediaServer.Proto/proto/settings.proto @@ -5,9 +5,18 @@ option csharp_namespace = "SnackTime.App.Settings.ProtoGenerated"; package snacktime.app.settings; message Settings { + LocalSystem system = 1; + Remote remote = 2; +} + +message LocalSystem{ string fileDir = 1; string tempFileDir = 2; string mpvPath = 3; string svpPath = 4; - string mediaServerAddress = 5; +} + +message Remote { + string mediaServerAddress = 1; + bool isOnline = 2; } \ No newline at end of file diff --git a/SnackTime.MediaServer.Proto/proto/status-service/status-ping.proto b/SnackTime.MediaServer.Proto/proto/status-service/status-ping.proto new file mode 100644 index 0000000..fd7f785 --- /dev/null +++ b/SnackTime.MediaServer.Proto/proto/status-service/status-ping.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +option csharp_namespace = "SnackTime.MediaServer.Service.Status"; + +package snacktime.status.service; + +message PingRequest { +} + +message PingResponse { +} \ No newline at end of file diff --git a/SnackTime.MediaServer.Proto/proto/status-service/status-service.proto b/SnackTime.MediaServer.Proto/proto/status-service/status-service.proto new file mode 100644 index 0000000..760818f --- /dev/null +++ b/SnackTime.MediaServer.Proto/proto/status-service/status-service.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +option csharp_namespace = "SnackTime.MediaServer.Service.Status"; + +package snacktime.status.service; + +import "proto/status-service/status-ping.proto"; + + +service Status { + rpc Ping (PingRequest) returns (PingResponse) { + } +} \ No newline at end of file diff --git a/SnackTime.MediaServer/DependencyModule.cs b/SnackTime.MediaServer/DependencyModule.cs index 9f1cf7a..f62f73b 100644 --- a/SnackTime.MediaServer/DependencyModule.cs +++ b/SnackTime.MediaServer/DependencyModule.cs @@ -1,5 +1,7 @@ using Autofac; +using SnackTime.Core; using SnackTime.Core.Media.Series; +using SnackTime.Core.Session; namespace SnackTime.MediaServer { @@ -7,13 +9,18 @@ public class DependencyModule : Module { protected override void Load(ContainerBuilder builder) { - builder.RegisterType().AsSelf(); - + + builder.RegisterType().As(); + builder.RegisterType().As(); + + builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); builder.Register(context => @@ -23,7 +30,8 @@ protected override void Load(ContainerBuilder builder) Service.Series.Series.BindService(context.Resolve()), Service.Episode.Episode.BindService(context.Resolve()), Service.File.File.BindService(context.Resolve()), - Service.Session.Session.BindService(context.Resolve()) + Service.Session.Session.BindService(context.Resolve()), + Service.Status.Status.BindService(context.Resolve()) }; return list; diff --git a/SnackTime.MediaServer/SessionController.cs b/SnackTime.MediaServer/SessionController.cs index 6f82f63..ac90cc0 100644 --- a/SnackTime.MediaServer/SessionController.cs +++ b/SnackTime.MediaServer/SessionController.cs @@ -7,26 +7,26 @@ namespace SnackTime.MediaServer { public class SessionController : Session.SessionBase { - private readonly SessionService _sessionService; + private readonly ILocalSessionRepo _localSessionRepo; - public SessionController(SessionService sessionService) + public SessionController(ILocalSessionRepo localSessionRepo) { - _sessionService = sessionService; + _localSessionRepo = localSessionRepo; } - public override Task GetAll(GetAllRequest request, ServerCallContext context) + public override async Task GetAll(GetAllRequest request, ServerCallContext context) { - var sessions = _sessionService.GetAll(); - return Task.FromResult(new GetAllResponse + var sessions = await _localSessionRepo.GetAll(); + return new GetAllResponse { Sessions = {sessions} - }); + }; } - public override Task Upsert(UpsertRequest request, ServerCallContext context) + public override async Task Upsert(UpsertRequest request, ServerCallContext context) { - _sessionService.UpsertSession(request.Session); - return Task.FromResult(new UpsertResponse()); + await _localSessionRepo.UpsertSession(request.Session); + return new UpsertResponse(); } } } \ No newline at end of file diff --git a/SnackTime.MediaServer/SessionRepoFactory.cs b/SnackTime.MediaServer/SessionRepoFactory.cs new file mode 100644 index 0000000..31920ee --- /dev/null +++ b/SnackTime.MediaServer/SessionRepoFactory.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using SnackTime.Core.Session; + +namespace SnackTime.MediaServer +{ + public class SessionRepoFactory : ISessionRepoFactory + { + private readonly ILocalSessionRepo _localSessionRepo; + + public SessionRepoFactory(ILocalSessionRepo localSessionRepo) + { + _localSessionRepo = localSessionRepo; + } + + public Task GetRepo() + { + return Task.FromResult(_localSessionRepo); + } + } +} \ No newline at end of file diff --git a/SnackTime.MediaServer/StatusController.cs b/SnackTime.MediaServer/StatusController.cs new file mode 100644 index 0000000..8d6cf7d --- /dev/null +++ b/SnackTime.MediaServer/StatusController.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using Grpc.Core; +using SnackTime.MediaServer.Service.Status; +using Status = SnackTime.MediaServer.Service.Status.Status; + +namespace SnackTime.MediaServer +{ + public class StatusController : Status.StatusBase + { + public override Task Ping(PingRequest request, ServerCallContext context) + { + return Task.FromResult(new PingResponse()); + } + } +} \ No newline at end of file diff --git a/SnackTime.WebApi/Controllers/EpisodeController.cs b/SnackTime.WebApi/Controllers/EpisodeController.cs index d8f56d1..9c40b79 100644 --- a/SnackTime.WebApi/Controllers/EpisodeController.cs +++ b/SnackTime.WebApi/Controllers/EpisodeController.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using SnackTime.Core; using SnackTime.MediaServer.Service.Episode; using SnackTime.WebApi.Helpers; diff --git a/SnackTime.WebApi/Controllers/HistoryController.cs b/SnackTime.WebApi/Controllers/HistoryController.cs index e9d61f0..b7843d4 100644 --- a/SnackTime.WebApi/Controllers/HistoryController.cs +++ b/SnackTime.WebApi/Controllers/HistoryController.cs @@ -1,6 +1,8 @@ using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using SnackTime.Core.Session; +using SnackTime.WebApi.Services; namespace SnackTime.WebApi.Controllers { @@ -21,16 +23,17 @@ public ActionResult GetLatestWatched() public class HistoryService { - private readonly SessionService _sessionService; + private readonly ISessionRepoFactory _sessionRepoFactory; - public HistoryService(SessionService sessionService) + public HistoryService(ISessionRepoFactory sessionRepoFactory) { - _sessionService = sessionService; + _sessionRepoFactory = sessionRepoFactory; } - public MediaServer.Models.ProtoGenerated.Series GetLatestWatched() + public async Task GetLatestWatched() { - var sessions = _sessionService.GetAll(); + var sessionRepo = await _sessionRepoFactory.GetRepo(); + var sessions = await sessionRepo.GetAll(); sessions .OrderBy(session => session.EndUTC) @@ -40,6 +43,5 @@ public MediaServer.Models.ProtoGenerated.Series GetLatestWatched() return null; } - } } \ No newline at end of file diff --git a/SnackTime.WebApi/Controllers/SeriesController.cs b/SnackTime.WebApi/Controllers/SeriesController.cs index ab6a2ee..4a67926 100644 --- a/SnackTime.WebApi/Controllers/SeriesController.cs +++ b/SnackTime.WebApi/Controllers/SeriesController.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using SnackTime.Core; using SnackTime.MediaServer.Service.Series; using SnackTime.WebApi.Helpers; diff --git a/SnackTime.WebApi/Controllers/SessionController.cs b/SnackTime.WebApi/Controllers/SessionController.cs index 9d8642a..00470a7 100644 --- a/SnackTime.WebApi/Controllers/SessionController.cs +++ b/SnackTime.WebApi/Controllers/SessionController.cs @@ -11,20 +11,21 @@ namespace SnackTime.WebApi.Controllers public class SessionController : ControllerBase { private readonly ILogger _logger; - private readonly SessionService _sessionService; + private readonly ISessionRepoFactory _sessionRepoFactory; private readonly SessionSyncService _sessionSyncService; - public SessionController(ILogger logger, SessionService sessionService, SessionSyncService sessionSyncService) + public SessionController(ILogger logger, SessionSyncService sessionSyncService, ISessionRepoFactory sessionRepoFactory) { _logger = logger; - _sessionService = sessionService; _sessionSyncService = sessionSyncService; + _sessionRepoFactory = sessionRepoFactory; } [HttpGet("")] - public ActionResult GetAll() + public async Task GetAll() { - return Ok(_sessionService.GetAll()); + var session = await _sessionRepoFactory.GetRepo(); + return Ok(await session.GetAll()); } [HttpGet("sync")] diff --git a/SnackTime.WebApi/DependencyModule.cs b/SnackTime.WebApi/DependencyModule.cs index ab6d822..60ec77a 100644 --- a/SnackTime.WebApi/DependencyModule.cs +++ b/SnackTime.WebApi/DependencyModule.cs @@ -1,11 +1,7 @@ using Autofac; -using Grpc.Core; using Microsoft.Extensions.Hosting; -using SnackTime.Core.Settings; -using SnackTime.MediaServer.Service.Episode; -using SnackTime.MediaServer.Service.File; -using SnackTime.MediaServer.Service.Series; -using SnackTime.MediaServer.Service.Session; +using SnackTime.Core; +using SnackTime.Core.Session; using SnackTime.WebApi.Services; namespace SnackTime.WebApi @@ -18,57 +14,12 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().As().SingleInstance(); builder.RegisterType().AsSelf(); + builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); - } - } - - public class GrpcClientProvider - { - private readonly SettingsService _settingsService; - - //TODO FIXT THIS! - private static Channel _lastChannel = new Channel("127.0.0.1:50052", ChannelCredentials.Insecure); - private static string _lastAddress = "127.0.0.1"; - - public GrpcClientProvider(SettingsService settingsService) - { - _settingsService = settingsService; - } - - - public Series.SeriesClient GetSeriesClient() - { - return new Series.SeriesClient(GetChannel()); - } - - public Episode.EpisodeClient GetEpisodeClient() - { - return new Episode.EpisodeClient(GetChannel()); - } - - public File.FileClient GetFileClient() - { - return new File.FileClient(GetChannel()); - } - - public Session.SessionClient GetSessionClient() - { - return new Session.SessionClient(GetChannel()); - } - - private Channel GetChannel() - { - var address = _settingsService.Get().MediaServerAddress; - if (_lastAddress == address) - { - return _lastChannel; - } - - _lastAddress = address; - _lastChannel = new Channel(_lastAddress, 50052, ChannelCredentials.Insecure); - - return _lastChannel; + + builder.RegisterType().As(); + builder.RegisterType().As(); } } } \ No newline at end of file diff --git a/SnackTime.WebApi/MediaPlayerObserver.cs b/SnackTime.WebApi/MediaPlayerObserver.cs index c30181e..96a8ba4 100644 --- a/SnackTime.WebApi/MediaPlayerObserver.cs +++ b/SnackTime.WebApi/MediaPlayerObserver.cs @@ -6,25 +6,34 @@ using SnackTime.Core; using SnackTime.Core.Session; using SnackTime.MediaServer.Storage.ProtoGenerated; +using SnackTime.WebApi.Services; namespace SnackTime.WebApi { public class MediaPlayerObserver : IHostedService { - private readonly Queue _queue; - private readonly SessionService _sessionService; - private readonly IApi _api; - private readonly TimeService _timeService; + private readonly Queue _queue; + private readonly SessionFactory _sessionFactory; + private readonly IApi _api; + private readonly TimeService _timeService; + private readonly ISessionRepoFactory _sessionRepoFactory; private CancellationToken _token; private Task _task; - public MediaPlayerObserver(Queue queue, SessionService sessionService, IApi api, TimeService timeService) + public MediaPlayerObserver + ( + Queue queue, + SessionFactory sessionFactory, + IApi api, TimeService timeService, + ISessionRepoFactory sessionRepoFactory + ) { _queue = queue; - _sessionService = sessionService; + _sessionFactory = sessionFactory; _api = api; _timeService = timeService; + _sessionRepoFactory = sessionRepoFactory; } public Task StartAsync(CancellationToken cancellationToken) @@ -51,14 +60,16 @@ private async Task Tick() await _api.ShowText($"Now playing {item.Path.Substring(item.Path.LastIndexOf('\\') + 1)}", TimeSpan.FromSeconds(5)); await _api.PlayMedia(item.Path); var duration = await _api.GetDuration(); - currentSession = _sessionService.CreateNewSession(item.MediaFileId, duration); + currentSession = _sessionFactory.CreateNewSession(item.MediaFileId, duration); } if (currentSession != null) { currentSession.Duration.EndPostionInSec = (await _api.GetCurrentPosition()).TotalSeconds; currentSession.EndUTC = _timeService.GetCurrentTimeAsUnixSeconds(); - _sessionService.UpsertSession(currentSession); + + var sessionRepo = await _sessionRepoFactory.GetRepo(); + await sessionRepo.UpsertSession(currentSession); } //How do we create a new WatchSession? diff --git a/SnackTime.WebApi/Services/FileDownloadService.cs b/SnackTime.WebApi/Services/FileDownloadService.cs index 9602217..b227314 100644 --- a/SnackTime.WebApi/Services/FileDownloadService.cs +++ b/SnackTime.WebApi/Services/FileDownloadService.cs @@ -79,7 +79,7 @@ public async Task DownloadFile(MediaFileId id) fileStream.Dispose(); } - fileStream = File.Create(settings.TempFileDir + $"{fileName}.{currentTempFileIndex}.temp"); + fileStream = File.Create(settings.System.TempFileDir + $"{fileName}.{currentTempFileIndex}.temp"); currentTempFileIndex++; } @@ -102,10 +102,10 @@ public async Task DownloadFile(MediaFileId id) var sw = Stopwatch.StartNew(); var filePattern = $"{fileName}.*.temp"; - await _fileService.CombineMultipleFilesIntoSingleFile(settings.TempFileDir, filePattern, settings.FileDir + fileName); + await _fileService.CombineMultipleFilesIntoSingleFile(settings.System.TempFileDir, filePattern, settings.System.FileDir + fileName); string hash; - using (Stream source = File.OpenRead(settings.FileDir + fileName)) + using (Stream source = File.OpenRead(settings.System.FileDir + fileName)) using (var md5 = MD5.Create()) { var byteHash = md5.ComputeHash(source); diff --git a/SnackTime.WebApi/Services/GrpcClientProvider.cs b/SnackTime.WebApi/Services/GrpcClientProvider.cs new file mode 100644 index 0000000..9035297 --- /dev/null +++ b/SnackTime.WebApi/Services/GrpcClientProvider.cs @@ -0,0 +1,63 @@ +using Grpc.Core; +using SnackTime.Core.Settings; +using SnackTime.MediaServer.Service.Episode; +using SnackTime.MediaServer.Service.File; +using SnackTime.MediaServer.Service.Series; +using Status = SnackTime.MediaServer.Service.Status.Status; + +namespace SnackTime.Core +{ + public class GrpcClientProvider + { + private readonly SettingsService _settingsService; + + //TODO FIXT THIS! + private static Channel _lastChannel = new Channel("127.0.0.1:50052", ChannelCredentials.Insecure); + private static string _lastAddress = "127.0.0.1"; + + public GrpcClientProvider(SettingsService settingsService) + { + _settingsService = settingsService; + } + + + public Series.SeriesClient GetSeriesClient() + { + return new Series.SeriesClient(GetChannel()); + } + + public Episode.EpisodeClient GetEpisodeClient() + { + return new Episode.EpisodeClient(GetChannel()); + } + + public File.FileClient GetFileClient() + { + return new File.FileClient(GetChannel()); + } + + public MediaServer.Service.Session.Session.SessionClient GetSessionClient() + { + return new MediaServer.Service.Session.Session.SessionClient(GetChannel()); + } + + public Status.StatusClient GetStatusClient() + { + return new Status.StatusClient(GetChannel()); + } + + private Channel GetChannel() + { + var address = _settingsService.Get().Remote.MediaServerAddress; + if (_lastAddress == address) + { + return _lastChannel; + } + + _lastAddress = address; + _lastChannel = new Channel(_lastAddress, 50052, ChannelCredentials.Insecure); + + return _lastChannel; + } + } +} \ No newline at end of file diff --git a/SnackTime.WebApi/Services/RemoteSessionRepo.cs b/SnackTime.WebApi/Services/RemoteSessionRepo.cs new file mode 100644 index 0000000..24837f7 --- /dev/null +++ b/SnackTime.WebApi/Services/RemoteSessionRepo.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using SnackTime.Core; +using SnackTime.Core.Session; +using SnackTime.MediaServer.Service.Session; + +namespace SnackTime.WebApi.Services +{ + public class RemoteSessionRepo : IRemoteSessionRepo + { + private readonly Session.SessionClient _sessionClient; + + public RemoteSessionRepo(GrpcClientProvider clientProvider) + { + _sessionClient = clientProvider.GetSessionClient(); + } + + public async Task UpsertSession(MediaServer.Storage.ProtoGenerated.Session session) + { + await _sessionClient.UpsertAsync(new UpsertRequest + { + Session = session + }); + } + + public async Task> GetAll() + { + var res = await _sessionClient.GetAllAsync(new GetAllRequest()); + return res.Sessions.ToList(); + } + } +} \ No newline at end of file diff --git a/SnackTime.WebApi/Services/SessionRepoFactory.cs b/SnackTime.WebApi/Services/SessionRepoFactory.cs new file mode 100644 index 0000000..501ff67 --- /dev/null +++ b/SnackTime.WebApi/Services/SessionRepoFactory.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using SnackTime.Core.Session; + +namespace SnackTime.WebApi.Services +{ + public class SessionRepoFactory : ISessionRepoFactory + { + private readonly ILocalSessionRepo _localSessionRepo; + private readonly IRemoteSessionRepo _remoteSessionRepo; + private readonly StatusService _statusService; + + public SessionRepoFactory(ILocalSessionRepo localSessionRepo, IRemoteSessionRepo remoteSessionRepo, StatusService statusService) + { + _localSessionRepo = localSessionRepo; + _remoteSessionRepo = remoteSessionRepo; + _statusService = statusService; + } + + public async Task GetRepo() + { + if (await _statusService.IsOnline()) + { + return _remoteSessionRepo; + } + + return _localSessionRepo; + } + } +} \ No newline at end of file diff --git a/SnackTime.WebApi/Services/SessionSyncService.cs b/SnackTime.WebApi/Services/SessionSyncService.cs index 65f7234..784a117 100644 --- a/SnackTime.WebApi/Services/SessionSyncService.cs +++ b/SnackTime.WebApi/Services/SessionSyncService.cs @@ -1,45 +1,57 @@ +using System; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using SnackTime.Core.Session; -using SnackTime.MediaServer.Service.Session; +using SnackTime.Core.Settings; namespace SnackTime.WebApi.Services { public class SessionSyncService { private readonly ILogger _logger; - private readonly SessionService _sessionService; - private readonly Session.SessionClient _sessionClient; + private readonly ILocalSessionRepo _localSessionRepo; + private readonly IRemoteSessionRepo _remoteSessionRepo; + private readonly SettingsService _settingsService; - public SessionSyncService(ILogger logger, SessionService sessionService, GrpcClientProvider clientProvider) + public SessionSyncService + ( + ILogger logger, + ILocalSessionRepo localSessionRepo, + IRemoteSessionRepo remoteSessionRepo, + SettingsService settingsService + ) { _logger = logger; - _sessionService = sessionService; - _sessionClient = clientProvider.GetSessionClient(); + _localSessionRepo = localSessionRepo; + _remoteSessionRepo = remoteSessionRepo; + _settingsService = settingsService; } public async Task Sync() { + var settings = _settingsService.Get(); + if (!settings.Remote.IsOnline) + { + throw new Exception("Can't sync servers when we are offline"); + } + _logger.LogInformation("Starting sync of sessions"); - var sessions = _sessionService.GetAll(); - var response = await _sessionClient.GetAllAsync(new GetAllRequest()); + var localSessions = await _localSessionRepo.GetAll(); + var remoteSessions = await _remoteSessionRepo.GetAll(); - _logger.LogDebug($"Have {sessions.Count} sessions locally"); - _logger.LogDebug($"Have {response.Sessions.Count} sessions on server"); + _logger.LogDebug($"Have {localSessions.Count} sessions locally"); + _logger.LogDebug($"Have {remoteSessions.Count} sessions on server"); - foreach (var session in sessions) + foreach (var session in localSessions) { _logger.LogDebug($"Upsert {session.Id} to server"); - _sessionClient.Upsert(new UpsertRequest - { - Session = session - }); + await _remoteSessionRepo.UpsertSession(session); } - foreach (var session in response.Sessions) + foreach (var session in remoteSessions) { _logger.LogDebug($"Upsert {session.Id} locally"); - _sessionService.UpsertSession(session); + await _localSessionRepo.UpsertSession(session); } } } diff --git a/SnackTime.WebApi/Services/StatusService.cs b/SnackTime.WebApi/Services/StatusService.cs new file mode 100644 index 0000000..6d3c038 --- /dev/null +++ b/SnackTime.WebApi/Services/StatusService.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using SnackTime.Core; +using SnackTime.Core.Database; +using SnackTime.Core.Session; +using SnackTime.Core.Settings; +using SnackTime.MediaServer.Service.Status; +using Status = SnackTime.MediaServer.Service.Status.Status; + +namespace SnackTime.WebApi.Services +{ + public class StatusService + { + private readonly ILogger _logger; + private readonly SettingsService _settingsService; + private readonly Status.StatusClient _statusClient; + + public StatusService(ILogger logger, GrpcClientProvider clientProvider, SettingsService settingsService) + { + _logger = logger; + _settingsService = settingsService; + _statusClient = clientProvider.GetStatusClient(); + } + + public async Task IsOnline() + { + if (!_settingsService.Get().Remote.IsOnline) + { + _logger.LogDebug("Remote is not enabled"); + return false; + } + + try + { + await _statusClient.PingAsync(new PingRequest(), deadline: DateTime.UtcNow.AddSeconds(2)); + _logger.LogDebug("Media server is up and running"); + return true; + } + catch (Exception e) + { + _logger.LogDebug("Could not connect to the media server"); + return false; + } + } + } +} \ No newline at end of file diff --git a/app/src/logic/api/protogen/types.d.ts b/app/src/logic/api/protogen/types.d.ts index 8f735d0..80209eb 100644 --- a/app/src/logic/api/protogen/types.d.ts +++ b/app/src/logic/api/protogen/types.d.ts @@ -147,11 +147,11 @@ export namespace snacktime { } } - /** Namespace series. */ - namespace series { + /** Namespace file. */ + namespace file { - /** Namespace file. */ - namespace file { + /** Namespace service. */ + namespace service { /** Properties of a DownloadFileRequest. */ interface IDownloadFileRequest { @@ -167,7 +167,7 @@ export namespace snacktime { * Constructs a new DownloadFileRequest. * @param [properties] Properties to set */ - constructor(properties?: snacktime.series.file.IDownloadFileRequest); + constructor(properties?: snacktime.file.service.IDownloadFileRequest); /** DownloadFileRequest mediaFileId. */ public mediaFileId: string; @@ -177,13 +177,13 @@ export namespace snacktime { interface IResponseDownloadFile { /** ResponseDownloadFile started */ - started?: (snacktime.series.file.IStarted|null); + started?: (snacktime.file.service.IStarted|null); /** ResponseDownloadFile progress */ - progress?: (snacktime.series.file.IChunk|null); + progress?: (snacktime.file.service.IChunk|null); /** ResponseDownloadFile done */ - done?: (snacktime.series.file.IDone|null); + done?: (snacktime.file.service.IDone|null); } /** Represents a ResponseDownloadFile. */ @@ -193,16 +193,16 @@ export namespace snacktime { * Constructs a new ResponseDownloadFile. * @param [properties] Properties to set */ - constructor(properties?: snacktime.series.file.IResponseDownloadFile); + constructor(properties?: snacktime.file.service.IResponseDownloadFile); /** ResponseDownloadFile started. */ - public started?: (snacktime.series.file.IStarted|null); + public started?: (snacktime.file.service.IStarted|null); /** ResponseDownloadFile progress. */ - public progress?: (snacktime.series.file.IChunk|null); + public progress?: (snacktime.file.service.IChunk|null); /** ResponseDownloadFile done. */ - public done?: (snacktime.series.file.IDone|null); + public done?: (snacktime.file.service.IDone|null); /** ResponseDownloadFile type. */ public type?: ("started"|"progress"|"done"); @@ -228,7 +228,7 @@ export namespace snacktime { * Constructs a new Started. * @param [properties] Properties to set */ - constructor(properties?: snacktime.series.file.IStarted); + constructor(properties?: snacktime.file.service.IStarted); /** Started lenght. */ public lenght: number; @@ -254,7 +254,7 @@ export namespace snacktime { * Constructs a new Chunk. * @param [properties] Properties to set */ - constructor(properties?: snacktime.series.file.IChunk); + constructor(properties?: snacktime.file.service.IChunk); /** Chunk Content. */ public Content: Uint8Array; @@ -274,7 +274,7 @@ export namespace snacktime { * Constructs a new Done. * @param [properties] Properties to set */ - constructor(properties?: snacktime.series.file.IDone); + constructor(properties?: snacktime.file.service.IDone); /** Done Hash. */ public Hash: string; @@ -296,26 +296,178 @@ export namespace snacktime { * @param request DownloadFileRequest message or plain object * @param callback Node-style callback called with the error, if any, and ResponseDownloadFile */ - public download(request: snacktime.series.file.IDownloadFileRequest, callback: snacktime.series.file.File.DownloadCallback): void; + public download(request: snacktime.file.service.IDownloadFileRequest, callback: snacktime.file.service.File.DownloadCallback): void; /** * Calls Download. * @param request DownloadFileRequest message or plain object * @returns Promise */ - public download(request: snacktime.series.file.IDownloadFileRequest): Promise; + public download(request: snacktime.file.service.IDownloadFileRequest): Promise; } namespace File { /** - * Callback as used by {@link snacktime.series.file.File#download}. + * Callback as used by {@link snacktime.file.service.File#download}. * @param error Error, if any * @param [response] ResponseDownloadFile */ - type DownloadCallback = (error: (Error|null), response?: snacktime.series.file.ResponseDownloadFile) => void; + type DownloadCallback = (error: (Error|null), response?: snacktime.file.service.ResponseDownloadFile) => void; } } + } + + /** Namespace media. */ + namespace media { + + /** Properties of a Series. */ + interface ISeries { + + /** Series id */ + id?: (number|null); + + /** Series title */ + title?: (string|null); + + /** Series imagesUrl */ + imagesUrl?: (snacktime.media.IImagesUrl|null); + + /** Series overview */ + overview?: (string|null); + + /** Series monitored */ + monitored?: (boolean|null); + } + + /** Represents a Series. */ + class Series implements ISeries { + + /** + * Constructs a new Series. + * @param [properties] Properties to set + */ + constructor(properties?: snacktime.media.ISeries); + + /** Series id. */ + public id: number; + + /** Series title. */ + public title: string; + + /** Series imagesUrl. */ + public imagesUrl?: (snacktime.media.IImagesUrl|null); + + /** Series overview. */ + public overview: string; + + /** Series monitored. */ + public monitored: boolean; + } + + /** Properties of an ImagesUrl. */ + interface IImagesUrl { + + /** ImagesUrl banner */ + banner?: (string|null); + + /** ImagesUrl fanart */ + fanart?: (string|null); + + /** ImagesUrl poster */ + poster?: (string|null); + } + + /** Represents an ImagesUrl. */ + class ImagesUrl implements IImagesUrl { + + /** + * Constructs a new ImagesUrl. + * @param [properties] Properties to set + */ + constructor(properties?: snacktime.media.IImagesUrl); + + /** ImagesUrl banner. */ + public banner: string; + + /** ImagesUrl fanart. */ + public fanart: string; + + /** ImagesUrl poster. */ + public poster: string; + } + + /** Properties of an Episode. */ + interface IEpisode { + + /** Episode seriesId */ + seriesId?: (number|null); + + /** Episode episodeFileId */ + episodeFileId?: (number|null); + + /** Episode seasonNumber */ + seasonNumber?: (number|null); + + /** Episode episideNumber */ + episideNumber?: (number|null); + + /** Episode title */ + title?: (string|null); + + /** Episode overview */ + overview?: (string|null); + + /** Episode playableId */ + playableId?: (string|null); + + /** Episode progress */ + progress?: (snacktime.storage.IProgress|null); + } + + /** Represents an Episode. */ + class Episode implements IEpisode { + + /** + * Constructs a new Episode. + * @param [properties] Properties to set + */ + constructor(properties?: snacktime.media.IEpisode); + + /** Episode seriesId. */ + public seriesId: number; + + /** Episode episodeFileId. */ + public episodeFileId: number; + + /** Episode seasonNumber. */ + public seasonNumber: number; + + /** Episode episideNumber. */ + public episideNumber: number; + + /** Episode title. */ + public title: string; + + /** Episode overview. */ + public overview: string; + + /** Episode playableId. */ + public playableId: string; + + /** Episode progress. */ + public progress?: (snacktime.storage.IProgress|null); + } + + /** Providers enum. */ + enum Providers { + Sonarr = 0, + Radarr = 1 + } + } + + /** Namespace series. */ + namespace series { /** Namespace service. */ namespace service { @@ -637,202 +789,172 @@ export namespace snacktime { } } - /** Namespace media. */ - namespace media { - - /** Properties of a Series. */ - interface ISeries { - - /** Series id */ - id?: (number|null); - - /** Series title */ - title?: (string|null); - - /** Series imagesUrl */ - imagesUrl?: (snacktime.media.IImagesUrl|null); - - /** Series overview */ - overview?: (string|null); - - /** Series monitored */ - monitored?: (boolean|null); - } - - /** Represents a Series. */ - class Series implements ISeries { - - /** - * Constructs a new Series. - * @param [properties] Properties to set - */ - constructor(properties?: snacktime.media.ISeries); - - /** Series id. */ - public id: number; - - /** Series title. */ - public title: string; - - /** Series imagesUrl. */ - public imagesUrl?: (snacktime.media.IImagesUrl|null); - - /** Series overview. */ - public overview: string; - - /** Series monitored. */ - public monitored: boolean; - } - - /** Properties of an ImagesUrl. */ - interface IImagesUrl { - - /** ImagesUrl banner */ - banner?: (string|null); + /** Namespace app. */ + namespace app { - /** ImagesUrl fanart */ - fanart?: (string|null); + /** Namespace settings. */ + namespace settings { - /** ImagesUrl poster */ - poster?: (string|null); - } + /** Properties of a Settings. */ + interface ISettings { - /** Represents an ImagesUrl. */ - class ImagesUrl implements IImagesUrl { + /** Settings system */ + system?: (snacktime.app.settings.ILocalSystem|null); - /** - * Constructs a new ImagesUrl. - * @param [properties] Properties to set - */ - constructor(properties?: snacktime.media.IImagesUrl); - - /** ImagesUrl banner. */ - public banner: string; + /** Settings remote */ + remote?: (snacktime.app.settings.IRemote|null); + } - /** ImagesUrl fanart. */ - public fanart: string; + /** Represents a Settings. */ + class Settings implements ISettings { - /** ImagesUrl poster. */ - public poster: string; - } + /** + * Constructs a new Settings. + * @param [properties] Properties to set + */ + constructor(properties?: snacktime.app.settings.ISettings); - /** Properties of an Episode. */ - interface IEpisode { + /** Settings system. */ + public system?: (snacktime.app.settings.ILocalSystem|null); - /** Episode seriesId */ - seriesId?: (number|null); + /** Settings remote. */ + public remote?: (snacktime.app.settings.IRemote|null); + } - /** Episode episodeFileId */ - episodeFileId?: (number|null); + /** Properties of a LocalSystem. */ + interface ILocalSystem { - /** Episode seasonNumber */ - seasonNumber?: (number|null); + /** LocalSystem fileDir */ + fileDir?: (string|null); - /** Episode episideNumber */ - episideNumber?: (number|null); + /** LocalSystem tempFileDir */ + tempFileDir?: (string|null); - /** Episode title */ - title?: (string|null); + /** LocalSystem mpvPath */ + mpvPath?: (string|null); - /** Episode overview */ - overview?: (string|null); + /** LocalSystem svpPath */ + svpPath?: (string|null); + } - /** Episode playableId */ - playableId?: (string|null); + /** Represents a LocalSystem. */ + class LocalSystem implements ILocalSystem { - /** Episode progress */ - progress?: (snacktime.storage.IProgress|null); - } + /** + * Constructs a new LocalSystem. + * @param [properties] Properties to set + */ + constructor(properties?: snacktime.app.settings.ILocalSystem); - /** Represents an Episode. */ - class Episode implements IEpisode { + /** LocalSystem fileDir. */ + public fileDir: string; - /** - * Constructs a new Episode. - * @param [properties] Properties to set - */ - constructor(properties?: snacktime.media.IEpisode); + /** LocalSystem tempFileDir. */ + public tempFileDir: string; - /** Episode seriesId. */ - public seriesId: number; + /** LocalSystem mpvPath. */ + public mpvPath: string; - /** Episode episodeFileId. */ - public episodeFileId: number; + /** LocalSystem svpPath. */ + public svpPath: string; + } - /** Episode seasonNumber. */ - public seasonNumber: number; + /** Properties of a Remote. */ + interface IRemote { - /** Episode episideNumber. */ - public episideNumber: number; + /** Remote mediaServerAddress */ + mediaServerAddress?: (string|null); - /** Episode title. */ - public title: string; + /** Remote isOnline */ + isOnline?: (boolean|null); + } - /** Episode overview. */ - public overview: string; + /** Represents a Remote. */ + class Remote implements IRemote { - /** Episode playableId. */ - public playableId: string; + /** + * Constructs a new Remote. + * @param [properties] Properties to set + */ + constructor(properties?: snacktime.app.settings.IRemote); - /** Episode progress. */ - public progress?: (snacktime.storage.IProgress|null); - } + /** Remote mediaServerAddress. */ + public mediaServerAddress: string; - /** Providers enum. */ - enum Providers { - Sonarr = 0, - Radarr = 1 + /** Remote isOnline. */ + public isOnline: boolean; + } } } - /** Namespace app. */ - namespace app { + /** Namespace status. */ + namespace status { - /** Namespace settings. */ - namespace settings { - - /** Properties of a Settings. */ - interface ISettings { - - /** Settings fileDir */ - fileDir?: (string|null); + /** Namespace service. */ + namespace service { - /** Settings tempFileDir */ - tempFileDir?: (string|null); + /** Properties of a PingRequest. */ + interface IPingRequest { + } - /** Settings mpvPath */ - mpvPath?: (string|null); + /** Represents a PingRequest. */ + class PingRequest implements IPingRequest { - /** Settings svpPath */ - svpPath?: (string|null); + /** + * Constructs a new PingRequest. + * @param [properties] Properties to set + */ + constructor(properties?: snacktime.status.service.IPingRequest); + } - /** Settings mediaServerAddress */ - mediaServerAddress?: (string|null); + /** Properties of a PingResponse. */ + interface IPingResponse { } - /** Represents a Settings. */ - class Settings implements ISettings { + /** Represents a PingResponse. */ + class PingResponse implements IPingResponse { /** - * Constructs a new Settings. + * Constructs a new PingResponse. * @param [properties] Properties to set */ - constructor(properties?: snacktime.app.settings.ISettings); + constructor(properties?: snacktime.status.service.IPingResponse); + } - /** Settings fileDir. */ - public fileDir: string; + /** Represents a Status */ + class Status extends $protobuf.rpc.Service { - /** Settings tempFileDir. */ - public tempFileDir: string; + /** + * Constructs a new Status service. + * @param rpcImpl RPC implementation + * @param [requestDelimited=false] Whether requests are length-delimited + * @param [responseDelimited=false] Whether responses are length-delimited + */ + constructor(rpcImpl: $protobuf.RPCImpl, requestDelimited?: boolean, responseDelimited?: boolean); - /** Settings mpvPath. */ - public mpvPath: string; + /** + * Calls Ping. + * @param request PingRequest message or plain object + * @param callback Node-style callback called with the error, if any, and PingResponse + */ + public ping(request: snacktime.status.service.IPingRequest, callback: snacktime.status.service.Status.PingCallback): void; - /** Settings svpPath. */ - public svpPath: string; + /** + * Calls Ping. + * @param request PingRequest message or plain object + * @returns Promise + */ + public ping(request: snacktime.status.service.IPingRequest): Promise; + } - /** Settings mediaServerAddress. */ - public mediaServerAddress: string; + namespace Status { + + /** + * Callback as used by {@link snacktime.status.service.Status#ping}. + * @param error Error, if any + * @param [response] PingResponse + */ + type PingCallback = (error: (Error|null), response?: snacktime.status.service.PingResponse) => void; } } } diff --git a/app/src/logic/api/protogen/types.js b/app/src/logic/api/protogen/types.js index 73a24c3..937e940 100644 --- a/app/src/logic/api/protogen/types.js +++ b/app/src/logic/api/protogen/types.js @@ -268,40 +268,40 @@ export const snacktime = $root.snacktime = (() => { return episode; })(); - snacktime.series = (function() { + snacktime.file = (function() { /** - * Namespace series. + * Namespace file. * @memberof snacktime * @namespace */ - const series = {}; + const file = {}; - series.file = (function() { + file.service = (function() { /** - * Namespace file. - * @memberof snacktime.series + * Namespace service. + * @memberof snacktime.file * @namespace */ - const file = {}; + const service = {}; - file.DownloadFileRequest = (function() { + service.DownloadFileRequest = (function() { /** * Properties of a DownloadFileRequest. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @interface IDownloadFileRequest * @property {string|null} [mediaFileId] DownloadFileRequest mediaFileId */ /** * Constructs a new DownloadFileRequest. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @classdesc Represents a DownloadFileRequest. * @implements IDownloadFileRequest * @constructor - * @param {snacktime.series.file.IDownloadFileRequest=} [properties] Properties to set + * @param {snacktime.file.service.IDownloadFileRequest=} [properties] Properties to set */ function DownloadFileRequest(properties) { if (properties) @@ -313,7 +313,7 @@ export const snacktime = $root.snacktime = (() => { /** * DownloadFileRequest mediaFileId. * @member {string} mediaFileId - * @memberof snacktime.series.file.DownloadFileRequest + * @memberof snacktime.file.service.DownloadFileRequest * @instance */ DownloadFileRequest.prototype.mediaFileId = ""; @@ -321,24 +321,24 @@ export const snacktime = $root.snacktime = (() => { return DownloadFileRequest; })(); - file.ResponseDownloadFile = (function() { + service.ResponseDownloadFile = (function() { /** * Properties of a ResponseDownloadFile. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @interface IResponseDownloadFile - * @property {snacktime.series.file.IStarted|null} [started] ResponseDownloadFile started - * @property {snacktime.series.file.IChunk|null} [progress] ResponseDownloadFile progress - * @property {snacktime.series.file.IDone|null} [done] ResponseDownloadFile done + * @property {snacktime.file.service.IStarted|null} [started] ResponseDownloadFile started + * @property {snacktime.file.service.IChunk|null} [progress] ResponseDownloadFile progress + * @property {snacktime.file.service.IDone|null} [done] ResponseDownloadFile done */ /** * Constructs a new ResponseDownloadFile. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @classdesc Represents a ResponseDownloadFile. * @implements IResponseDownloadFile * @constructor - * @param {snacktime.series.file.IResponseDownloadFile=} [properties] Properties to set + * @param {snacktime.file.service.IResponseDownloadFile=} [properties] Properties to set */ function ResponseDownloadFile(properties) { if (properties) @@ -349,24 +349,24 @@ export const snacktime = $root.snacktime = (() => { /** * ResponseDownloadFile started. - * @member {snacktime.series.file.IStarted|null|undefined} started - * @memberof snacktime.series.file.ResponseDownloadFile + * @member {snacktime.file.service.IStarted|null|undefined} started + * @memberof snacktime.file.service.ResponseDownloadFile * @instance */ ResponseDownloadFile.prototype.started = null; /** * ResponseDownloadFile progress. - * @member {snacktime.series.file.IChunk|null|undefined} progress - * @memberof snacktime.series.file.ResponseDownloadFile + * @member {snacktime.file.service.IChunk|null|undefined} progress + * @memberof snacktime.file.service.ResponseDownloadFile * @instance */ ResponseDownloadFile.prototype.progress = null; /** * ResponseDownloadFile done. - * @member {snacktime.series.file.IDone|null|undefined} done - * @memberof snacktime.series.file.ResponseDownloadFile + * @member {snacktime.file.service.IDone|null|undefined} done + * @memberof snacktime.file.service.ResponseDownloadFile * @instance */ ResponseDownloadFile.prototype.done = null; @@ -377,7 +377,7 @@ export const snacktime = $root.snacktime = (() => { /** * ResponseDownloadFile type. * @member {"started"|"progress"|"done"|undefined} type - * @memberof snacktime.series.file.ResponseDownloadFile + * @memberof snacktime.file.service.ResponseDownloadFile * @instance */ Object.defineProperty(ResponseDownloadFile.prototype, "type", { @@ -388,11 +388,11 @@ export const snacktime = $root.snacktime = (() => { return ResponseDownloadFile; })(); - file.Started = (function() { + service.Started = (function() { /** * Properties of a Started. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @interface IStarted * @property {number|null} [lenght] Started lenght * @property {number|null} [sizePerChunk] Started sizePerChunk @@ -401,11 +401,11 @@ export const snacktime = $root.snacktime = (() => { /** * Constructs a new Started. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @classdesc Represents a Started. * @implements IStarted * @constructor - * @param {snacktime.series.file.IStarted=} [properties] Properties to set + * @param {snacktime.file.service.IStarted=} [properties] Properties to set */ function Started(properties) { if (properties) @@ -417,7 +417,7 @@ export const snacktime = $root.snacktime = (() => { /** * Started lenght. * @member {number} lenght - * @memberof snacktime.series.file.Started + * @memberof snacktime.file.service.Started * @instance */ Started.prototype.lenght = 0; @@ -425,7 +425,7 @@ export const snacktime = $root.snacktime = (() => { /** * Started sizePerChunk. * @member {number} sizePerChunk - * @memberof snacktime.series.file.Started + * @memberof snacktime.file.service.Started * @instance */ Started.prototype.sizePerChunk = 0; @@ -433,7 +433,7 @@ export const snacktime = $root.snacktime = (() => { /** * Started FileName. * @member {string} FileName - * @memberof snacktime.series.file.Started + * @memberof snacktime.file.service.Started * @instance */ Started.prototype.FileName = ""; @@ -441,22 +441,22 @@ export const snacktime = $root.snacktime = (() => { return Started; })(); - file.Chunk = (function() { + service.Chunk = (function() { /** * Properties of a Chunk. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @interface IChunk * @property {Uint8Array|null} [Content] Chunk Content */ /** * Constructs a new Chunk. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @classdesc Represents a Chunk. * @implements IChunk * @constructor - * @param {snacktime.series.file.IChunk=} [properties] Properties to set + * @param {snacktime.file.service.IChunk=} [properties] Properties to set */ function Chunk(properties) { if (properties) @@ -468,7 +468,7 @@ export const snacktime = $root.snacktime = (() => { /** * Chunk Content. * @member {Uint8Array} Content - * @memberof snacktime.series.file.Chunk + * @memberof snacktime.file.service.Chunk * @instance */ Chunk.prototype.Content = $util.newBuffer([]); @@ -476,22 +476,22 @@ export const snacktime = $root.snacktime = (() => { return Chunk; })(); - file.Done = (function() { + service.Done = (function() { /** * Properties of a Done. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @interface IDone * @property {string|null} [Hash] Done Hash */ /** * Constructs a new Done. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @classdesc Represents a Done. * @implements IDone * @constructor - * @param {snacktime.series.file.IDone=} [properties] Properties to set + * @param {snacktime.file.service.IDone=} [properties] Properties to set */ function Done(properties) { if (properties) @@ -503,7 +503,7 @@ export const snacktime = $root.snacktime = (() => { /** * Done Hash. * @member {string} Hash - * @memberof snacktime.series.file.Done + * @memberof snacktime.file.service.Done * @instance */ Done.prototype.Hash = ""; @@ -511,11 +511,11 @@ export const snacktime = $root.snacktime = (() => { return Done; })(); - file.File = (function() { + service.File = (function() { /** * Constructs a new File service. - * @memberof snacktime.series.file + * @memberof snacktime.file.service * @classdesc Represents a File * @extends $protobuf.rpc.Service * @constructor @@ -530,196 +530,456 @@ export const snacktime = $root.snacktime = (() => { (File.prototype = Object.create($protobuf.rpc.Service.prototype)).constructor = File; /** - * Callback as used by {@link snacktime.series.file.File#download}. - * @memberof snacktime.series.file.File + * Callback as used by {@link snacktime.file.service.File#download}. + * @memberof snacktime.file.service.File * @typedef DownloadCallback * @type {function} * @param {Error|null} error Error, if any - * @param {snacktime.series.file.ResponseDownloadFile} [response] ResponseDownloadFile + * @param {snacktime.file.service.ResponseDownloadFile} [response] ResponseDownloadFile */ /** * Calls Download. * @function download - * @memberof snacktime.series.file.File + * @memberof snacktime.file.service.File * @instance - * @param {snacktime.series.file.IDownloadFileRequest} request DownloadFileRequest message or plain object - * @param {snacktime.series.file.File.DownloadCallback} callback Node-style callback called with the error, if any, and ResponseDownloadFile + * @param {snacktime.file.service.IDownloadFileRequest} request DownloadFileRequest message or plain object + * @param {snacktime.file.service.File.DownloadCallback} callback Node-style callback called with the error, if any, and ResponseDownloadFile * @returns {undefined} * @variation 1 */ Object.defineProperty(File.prototype.download = function download(request, callback) { - return this.rpcCall(download, $root.snacktime.series.file.DownloadFileRequest, $root.snacktime.series.file.ResponseDownloadFile, request, callback); + return this.rpcCall(download, $root.snacktime.file.service.DownloadFileRequest, $root.snacktime.file.service.ResponseDownloadFile, request, callback); }, "name", { value: "Download" }); /** * Calls Download. * @function download - * @memberof snacktime.series.file.File + * @memberof snacktime.file.service.File * @instance - * @param {snacktime.series.file.IDownloadFileRequest} request DownloadFileRequest message or plain object - * @returns {Promise} Promise + * @param {snacktime.file.service.IDownloadFileRequest} request DownloadFileRequest message or plain object + * @returns {Promise} Promise * @variation 2 */ return File; })(); - return file; + return service; })(); - series.service = (function() { - - /** - * Namespace service. - * @memberof snacktime.series - * @namespace - */ - const service = {}; - - service.GetAllRequest = (function() { - - /** - * Properties of a GetAllRequest. - * @memberof snacktime.series.service - * @interface IGetAllRequest - */ + return file; + })(); - /** - * Constructs a new GetAllRequest. - * @memberof snacktime.series.service - * @classdesc Represents a GetAllRequest. - * @implements IGetAllRequest - * @constructor - * @param {snacktime.series.service.IGetAllRequest=} [properties] Properties to set - */ - function GetAllRequest(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + snacktime.media = (function() { - return GetAllRequest; - })(); + /** + * Namespace media. + * @memberof snacktime + * @namespace + */ + const media = {}; - service.GetAllResponse = (function() { + media.Series = (function() { - /** - * Properties of a GetAllResponse. - * @memberof snacktime.series.service - * @interface IGetAllResponse - * @property {Array.|null} [series] GetAllResponse series - */ + /** + * Properties of a Series. + * @memberof snacktime.media + * @interface ISeries + * @property {number|null} [id] Series id + * @property {string|null} [title] Series title + * @property {snacktime.media.IImagesUrl|null} [imagesUrl] Series imagesUrl + * @property {string|null} [overview] Series overview + * @property {boolean|null} [monitored] Series monitored + */ - /** - * Constructs a new GetAllResponse. - * @memberof snacktime.series.service - * @classdesc Represents a GetAllResponse. - * @implements IGetAllResponse - * @constructor - * @param {snacktime.series.service.IGetAllResponse=} [properties] Properties to set - */ - function GetAllResponse(properties) { - this.series = []; - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + /** + * Constructs a new Series. + * @memberof snacktime.media + * @classdesc Represents a Series. + * @implements ISeries + * @constructor + * @param {snacktime.media.ISeries=} [properties] Properties to set + */ + function Series(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } - /** - * GetAllResponse series. - * @member {Array.} series - * @memberof snacktime.series.service.GetAllResponse - * @instance - */ - GetAllResponse.prototype.series = $util.emptyArray; + /** + * Series id. + * @member {number} id + * @memberof snacktime.media.Series + * @instance + */ + Series.prototype.id = 0; - return GetAllResponse; - })(); + /** + * Series title. + * @member {string} title + * @memberof snacktime.media.Series + * @instance + */ + Series.prototype.title = ""; - service.GetByIdRequest = (function() { + /** + * Series imagesUrl. + * @member {snacktime.media.IImagesUrl|null|undefined} imagesUrl + * @memberof snacktime.media.Series + * @instance + */ + Series.prototype.imagesUrl = null; - /** - * Properties of a GetByIdRequest. - * @memberof snacktime.series.service - * @interface IGetByIdRequest - * @property {number|null} [id] GetByIdRequest id - */ + /** + * Series overview. + * @member {string} overview + * @memberof snacktime.media.Series + * @instance + */ + Series.prototype.overview = ""; - /** - * Constructs a new GetByIdRequest. - * @memberof snacktime.series.service - * @classdesc Represents a GetByIdRequest. - * @implements IGetByIdRequest - * @constructor - * @param {snacktime.series.service.IGetByIdRequest=} [properties] Properties to set - */ - function GetByIdRequest(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + /** + * Series monitored. + * @member {boolean} monitored + * @memberof snacktime.media.Series + * @instance + */ + Series.prototype.monitored = false; - /** - * GetByIdRequest id. - * @member {number} id - * @memberof snacktime.series.service.GetByIdRequest - * @instance - */ - GetByIdRequest.prototype.id = 0; + return Series; + })(); - return GetByIdRequest; - })(); + media.ImagesUrl = (function() { - service.GetByIdResponse = (function() { + /** + * Properties of an ImagesUrl. + * @memberof snacktime.media + * @interface IImagesUrl + * @property {string|null} [banner] ImagesUrl banner + * @property {string|null} [fanart] ImagesUrl fanart + * @property {string|null} [poster] ImagesUrl poster + */ - /** - * Properties of a GetByIdResponse. - * @memberof snacktime.series.service - * @interface IGetByIdResponse - * @property {snacktime.media.ISeries|null} [series] GetByIdResponse series - */ + /** + * Constructs a new ImagesUrl. + * @memberof snacktime.media + * @classdesc Represents an ImagesUrl. + * @implements IImagesUrl + * @constructor + * @param {snacktime.media.IImagesUrl=} [properties] Properties to set + */ + function ImagesUrl(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } - /** - * Constructs a new GetByIdResponse. - * @memberof snacktime.series.service - * @classdesc Represents a GetByIdResponse. - * @implements IGetByIdResponse - * @constructor - * @param {snacktime.series.service.IGetByIdResponse=} [properties] Properties to set - */ - function GetByIdResponse(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + /** + * ImagesUrl banner. + * @member {string} banner + * @memberof snacktime.media.ImagesUrl + * @instance + */ + ImagesUrl.prototype.banner = ""; - /** - * GetByIdResponse series. - * @member {snacktime.media.ISeries|null|undefined} series - * @memberof snacktime.series.service.GetByIdResponse - * @instance - */ - GetByIdResponse.prototype.series = null; + /** + * ImagesUrl fanart. + * @member {string} fanart + * @memberof snacktime.media.ImagesUrl + * @instance + */ + ImagesUrl.prototype.fanart = ""; - return GetByIdResponse; - })(); + /** + * ImagesUrl poster. + * @member {string} poster + * @memberof snacktime.media.ImagesUrl + * @instance + */ + ImagesUrl.prototype.poster = ""; - service.GetLastDownloadedRequest = (function() { + return ImagesUrl; + })(); - /** - * Properties of a GetLastDownloadedRequest. - * @memberof snacktime.series.service - * @interface IGetLastDownloadedRequest - */ + media.Episode = (function() { - /** - * Constructs a new GetLastDownloadedRequest. - * @memberof snacktime.series.service + /** + * Properties of an Episode. + * @memberof snacktime.media + * @interface IEpisode + * @property {number|null} [seriesId] Episode seriesId + * @property {number|null} [episodeFileId] Episode episodeFileId + * @property {number|null} [seasonNumber] Episode seasonNumber + * @property {number|null} [episideNumber] Episode episideNumber + * @property {string|null} [title] Episode title + * @property {string|null} [overview] Episode overview + * @property {string|null} [playableId] Episode playableId + * @property {snacktime.storage.IProgress|null} [progress] Episode progress + */ + + /** + * Constructs a new Episode. + * @memberof snacktime.media + * @classdesc Represents an Episode. + * @implements IEpisode + * @constructor + * @param {snacktime.media.IEpisode=} [properties] Properties to set + */ + function Episode(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Episode seriesId. + * @member {number} seriesId + * @memberof snacktime.media.Episode + * @instance + */ + Episode.prototype.seriesId = 0; + + /** + * Episode episodeFileId. + * @member {number} episodeFileId + * @memberof snacktime.media.Episode + * @instance + */ + Episode.prototype.episodeFileId = 0; + + /** + * Episode seasonNumber. + * @member {number} seasonNumber + * @memberof snacktime.media.Episode + * @instance + */ + Episode.prototype.seasonNumber = 0; + + /** + * Episode episideNumber. + * @member {number} episideNumber + * @memberof snacktime.media.Episode + * @instance + */ + Episode.prototype.episideNumber = 0; + + /** + * Episode title. + * @member {string} title + * @memberof snacktime.media.Episode + * @instance + */ + Episode.prototype.title = ""; + + /** + * Episode overview. + * @member {string} overview + * @memberof snacktime.media.Episode + * @instance + */ + Episode.prototype.overview = ""; + + /** + * Episode playableId. + * @member {string} playableId + * @memberof snacktime.media.Episode + * @instance + */ + Episode.prototype.playableId = ""; + + /** + * Episode progress. + * @member {snacktime.storage.IProgress|null|undefined} progress + * @memberof snacktime.media.Episode + * @instance + */ + Episode.prototype.progress = null; + + return Episode; + })(); + + /** + * Providers enum. + * @name snacktime.media.Providers + * @enum {string} + * @property {number} Sonarr=0 Sonarr value + * @property {number} Radarr=1 Radarr value + */ + media.Providers = (function() { + const valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "Sonarr"] = 0; + values[valuesById[1] = "Radarr"] = 1; + return values; + })(); + + return media; + })(); + + snacktime.series = (function() { + + /** + * Namespace series. + * @memberof snacktime + * @namespace + */ + const series = {}; + + series.service = (function() { + + /** + * Namespace service. + * @memberof snacktime.series + * @namespace + */ + const service = {}; + + service.GetAllRequest = (function() { + + /** + * Properties of a GetAllRequest. + * @memberof snacktime.series.service + * @interface IGetAllRequest + */ + + /** + * Constructs a new GetAllRequest. + * @memberof snacktime.series.service + * @classdesc Represents a GetAllRequest. + * @implements IGetAllRequest + * @constructor + * @param {snacktime.series.service.IGetAllRequest=} [properties] Properties to set + */ + function GetAllRequest(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + return GetAllRequest; + })(); + + service.GetAllResponse = (function() { + + /** + * Properties of a GetAllResponse. + * @memberof snacktime.series.service + * @interface IGetAllResponse + * @property {Array.|null} [series] GetAllResponse series + */ + + /** + * Constructs a new GetAllResponse. + * @memberof snacktime.series.service + * @classdesc Represents a GetAllResponse. + * @implements IGetAllResponse + * @constructor + * @param {snacktime.series.service.IGetAllResponse=} [properties] Properties to set + */ + function GetAllResponse(properties) { + this.series = []; + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * GetAllResponse series. + * @member {Array.} series + * @memberof snacktime.series.service.GetAllResponse + * @instance + */ + GetAllResponse.prototype.series = $util.emptyArray; + + return GetAllResponse; + })(); + + service.GetByIdRequest = (function() { + + /** + * Properties of a GetByIdRequest. + * @memberof snacktime.series.service + * @interface IGetByIdRequest + * @property {number|null} [id] GetByIdRequest id + */ + + /** + * Constructs a new GetByIdRequest. + * @memberof snacktime.series.service + * @classdesc Represents a GetByIdRequest. + * @implements IGetByIdRequest + * @constructor + * @param {snacktime.series.service.IGetByIdRequest=} [properties] Properties to set + */ + function GetByIdRequest(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * GetByIdRequest id. + * @member {number} id + * @memberof snacktime.series.service.GetByIdRequest + * @instance + */ + GetByIdRequest.prototype.id = 0; + + return GetByIdRequest; + })(); + + service.GetByIdResponse = (function() { + + /** + * Properties of a GetByIdResponse. + * @memberof snacktime.series.service + * @interface IGetByIdResponse + * @property {snacktime.media.ISeries|null} [series] GetByIdResponse series + */ + + /** + * Constructs a new GetByIdResponse. + * @memberof snacktime.series.service + * @classdesc Represents a GetByIdResponse. + * @implements IGetByIdResponse + * @constructor + * @param {snacktime.series.service.IGetByIdResponse=} [properties] Properties to set + */ + function GetByIdResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * GetByIdResponse series. + * @member {snacktime.media.ISeries|null|undefined} series + * @memberof snacktime.series.service.GetByIdResponse + * @instance + */ + GetByIdResponse.prototype.series = null; + + return GetByIdResponse; + })(); + + service.GetLastDownloadedRequest = (function() { + + /** + * Properties of a GetLastDownloadedRequest. + * @memberof snacktime.series.service + * @interface IGetLastDownloadedRequest + */ + + /** + * Constructs a new GetLastDownloadedRequest. + * @memberof snacktime.series.service * @classdesc Represents a GetLastDownloadedRequest. * @implements IGetLastDownloadedRequest * @constructor @@ -1047,324 +1307,76 @@ export const snacktime = $root.snacktime = (() => { * @param {snacktime.series.session.IUpsertRequest} request UpsertRequest message or plain object * @returns {Promise} Promise * @variation 2 - */ - - return Session; - })(); - - session.UpsertRequest = (function() { - - /** - * Properties of an UpsertRequest. - * @memberof snacktime.series.session - * @interface IUpsertRequest - * @property {snacktime.storage.ISession|null} [session] UpsertRequest session - */ - - /** - * Constructs a new UpsertRequest. - * @memberof snacktime.series.session - * @classdesc Represents an UpsertRequest. - * @implements IUpsertRequest - * @constructor - * @param {snacktime.series.session.IUpsertRequest=} [properties] Properties to set - */ - function UpsertRequest(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * UpsertRequest session. - * @member {snacktime.storage.ISession|null|undefined} session - * @memberof snacktime.series.session.UpsertRequest - * @instance - */ - UpsertRequest.prototype.session = null; - - return UpsertRequest; - })(); - - session.UpsertResponse = (function() { - - /** - * Properties of an UpsertResponse. - * @memberof snacktime.series.session - * @interface IUpsertResponse - */ - - /** - * Constructs a new UpsertResponse. - * @memberof snacktime.series.session - * @classdesc Represents an UpsertResponse. - * @implements IUpsertResponse - * @constructor - * @param {snacktime.series.session.IUpsertResponse=} [properties] Properties to set - */ - function UpsertResponse(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - return UpsertResponse; - })(); - - return session; - })(); - - return series; - })(); - - snacktime.media = (function() { - - /** - * Namespace media. - * @memberof snacktime - * @namespace - */ - const media = {}; - - media.Series = (function() { - - /** - * Properties of a Series. - * @memberof snacktime.media - * @interface ISeries - * @property {number|null} [id] Series id - * @property {string|null} [title] Series title - * @property {snacktime.media.IImagesUrl|null} [imagesUrl] Series imagesUrl - * @property {string|null} [overview] Series overview - * @property {boolean|null} [monitored] Series monitored - */ - - /** - * Constructs a new Series. - * @memberof snacktime.media - * @classdesc Represents a Series. - * @implements ISeries - * @constructor - * @param {snacktime.media.ISeries=} [properties] Properties to set - */ - function Series(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Series id. - * @member {number} id - * @memberof snacktime.media.Series - * @instance - */ - Series.prototype.id = 0; - - /** - * Series title. - * @member {string} title - * @memberof snacktime.media.Series - * @instance - */ - Series.prototype.title = ""; - - /** - * Series imagesUrl. - * @member {snacktime.media.IImagesUrl|null|undefined} imagesUrl - * @memberof snacktime.media.Series - * @instance - */ - Series.prototype.imagesUrl = null; - - /** - * Series overview. - * @member {string} overview - * @memberof snacktime.media.Series - * @instance - */ - Series.prototype.overview = ""; - - /** - * Series monitored. - * @member {boolean} monitored - * @memberof snacktime.media.Series - * @instance - */ - Series.prototype.monitored = false; - - return Series; - })(); - - media.ImagesUrl = (function() { - - /** - * Properties of an ImagesUrl. - * @memberof snacktime.media - * @interface IImagesUrl - * @property {string|null} [banner] ImagesUrl banner - * @property {string|null} [fanart] ImagesUrl fanart - * @property {string|null} [poster] ImagesUrl poster - */ - - /** - * Constructs a new ImagesUrl. - * @memberof snacktime.media - * @classdesc Represents an ImagesUrl. - * @implements IImagesUrl - * @constructor - * @param {snacktime.media.IImagesUrl=} [properties] Properties to set - */ - function ImagesUrl(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ImagesUrl banner. - * @member {string} banner - * @memberof snacktime.media.ImagesUrl - * @instance - */ - ImagesUrl.prototype.banner = ""; - - /** - * ImagesUrl fanart. - * @member {string} fanart - * @memberof snacktime.media.ImagesUrl - * @instance - */ - ImagesUrl.prototype.fanart = ""; - - /** - * ImagesUrl poster. - * @member {string} poster - * @memberof snacktime.media.ImagesUrl - * @instance - */ - ImagesUrl.prototype.poster = ""; - - return ImagesUrl; - })(); - - media.Episode = (function() { - - /** - * Properties of an Episode. - * @memberof snacktime.media - * @interface IEpisode - * @property {number|null} [seriesId] Episode seriesId - * @property {number|null} [episodeFileId] Episode episodeFileId - * @property {number|null} [seasonNumber] Episode seasonNumber - * @property {number|null} [episideNumber] Episode episideNumber - * @property {string|null} [title] Episode title - * @property {string|null} [overview] Episode overview - * @property {string|null} [playableId] Episode playableId - * @property {snacktime.storage.IProgress|null} [progress] Episode progress - */ - - /** - * Constructs a new Episode. - * @memberof snacktime.media - * @classdesc Represents an Episode. - * @implements IEpisode - * @constructor - * @param {snacktime.media.IEpisode=} [properties] Properties to set - */ - function Episode(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Episode seriesId. - * @member {number} seriesId - * @memberof snacktime.media.Episode - * @instance - */ - Episode.prototype.seriesId = 0; + */ - /** - * Episode episodeFileId. - * @member {number} episodeFileId - * @memberof snacktime.media.Episode - * @instance - */ - Episode.prototype.episodeFileId = 0; + return Session; + })(); - /** - * Episode seasonNumber. - * @member {number} seasonNumber - * @memberof snacktime.media.Episode - * @instance - */ - Episode.prototype.seasonNumber = 0; + session.UpsertRequest = (function() { - /** - * Episode episideNumber. - * @member {number} episideNumber - * @memberof snacktime.media.Episode - * @instance - */ - Episode.prototype.episideNumber = 0; + /** + * Properties of an UpsertRequest. + * @memberof snacktime.series.session + * @interface IUpsertRequest + * @property {snacktime.storage.ISession|null} [session] UpsertRequest session + */ - /** - * Episode title. - * @member {string} title - * @memberof snacktime.media.Episode - * @instance - */ - Episode.prototype.title = ""; + /** + * Constructs a new UpsertRequest. + * @memberof snacktime.series.session + * @classdesc Represents an UpsertRequest. + * @implements IUpsertRequest + * @constructor + * @param {snacktime.series.session.IUpsertRequest=} [properties] Properties to set + */ + function UpsertRequest(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } - /** - * Episode overview. - * @member {string} overview - * @memberof snacktime.media.Episode - * @instance - */ - Episode.prototype.overview = ""; + /** + * UpsertRequest session. + * @member {snacktime.storage.ISession|null|undefined} session + * @memberof snacktime.series.session.UpsertRequest + * @instance + */ + UpsertRequest.prototype.session = null; - /** - * Episode playableId. - * @member {string} playableId - * @memberof snacktime.media.Episode - * @instance - */ - Episode.prototype.playableId = ""; + return UpsertRequest; + })(); - /** - * Episode progress. - * @member {snacktime.storage.IProgress|null|undefined} progress - * @memberof snacktime.media.Episode - * @instance - */ - Episode.prototype.progress = null; + session.UpsertResponse = (function() { - return Episode; - })(); + /** + * Properties of an UpsertResponse. + * @memberof snacktime.series.session + * @interface IUpsertResponse + */ - /** - * Providers enum. - * @name snacktime.media.Providers - * @enum {string} - * @property {number} Sonarr=0 Sonarr value - * @property {number} Radarr=1 Radarr value - */ - media.Providers = (function() { - const valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "Sonarr"] = 0; - values[valuesById[1] = "Radarr"] = 1; - return values; + /** + * Constructs a new UpsertResponse. + * @memberof snacktime.series.session + * @classdesc Represents an UpsertResponse. + * @implements IUpsertResponse + * @constructor + * @param {snacktime.series.session.IUpsertResponse=} [properties] Properties to set + */ + function UpsertResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + return UpsertResponse; + })(); + + return session; })(); - return media; + return series; })(); snacktime.app = (function() { @@ -1391,11 +1403,8 @@ export const snacktime = $root.snacktime = (() => { * Properties of a Settings. * @memberof snacktime.app.settings * @interface ISettings - * @property {string|null} [fileDir] Settings fileDir - * @property {string|null} [tempFileDir] Settings tempFileDir - * @property {string|null} [mpvPath] Settings mpvPath - * @property {string|null} [svpPath] Settings svpPath - * @property {string|null} [mediaServerAddress] Settings mediaServerAddress + * @property {snacktime.app.settings.ILocalSystem|null} [system] Settings system + * @property {snacktime.app.settings.IRemote|null} [remote] Settings remote */ /** @@ -1414,46 +1423,128 @@ export const snacktime = $root.snacktime = (() => { } /** - * Settings fileDir. - * @member {string} fileDir + * Settings system. + * @member {snacktime.app.settings.ILocalSystem|null|undefined} system * @memberof snacktime.app.settings.Settings * @instance */ - Settings.prototype.fileDir = ""; + Settings.prototype.system = null; /** - * Settings tempFileDir. - * @member {string} tempFileDir + * Settings remote. + * @member {snacktime.app.settings.IRemote|null|undefined} remote * @memberof snacktime.app.settings.Settings * @instance */ - Settings.prototype.tempFileDir = ""; + Settings.prototype.remote = null; + + return Settings; + })(); + + settings.LocalSystem = (function() { + + /** + * Properties of a LocalSystem. + * @memberof snacktime.app.settings + * @interface ILocalSystem + * @property {string|null} [fileDir] LocalSystem fileDir + * @property {string|null} [tempFileDir] LocalSystem tempFileDir + * @property {string|null} [mpvPath] LocalSystem mpvPath + * @property {string|null} [svpPath] LocalSystem svpPath + */ + + /** + * Constructs a new LocalSystem. + * @memberof snacktime.app.settings + * @classdesc Represents a LocalSystem. + * @implements ILocalSystem + * @constructor + * @param {snacktime.app.settings.ILocalSystem=} [properties] Properties to set + */ + function LocalSystem(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LocalSystem fileDir. + * @member {string} fileDir + * @memberof snacktime.app.settings.LocalSystem + * @instance + */ + LocalSystem.prototype.fileDir = ""; + + /** + * LocalSystem tempFileDir. + * @member {string} tempFileDir + * @memberof snacktime.app.settings.LocalSystem + * @instance + */ + LocalSystem.prototype.tempFileDir = ""; /** - * Settings mpvPath. + * LocalSystem mpvPath. * @member {string} mpvPath - * @memberof snacktime.app.settings.Settings + * @memberof snacktime.app.settings.LocalSystem * @instance */ - Settings.prototype.mpvPath = ""; + LocalSystem.prototype.mpvPath = ""; /** - * Settings svpPath. + * LocalSystem svpPath. * @member {string} svpPath - * @memberof snacktime.app.settings.Settings + * @memberof snacktime.app.settings.LocalSystem * @instance */ - Settings.prototype.svpPath = ""; + LocalSystem.prototype.svpPath = ""; + + return LocalSystem; + })(); + + settings.Remote = (function() { + + /** + * Properties of a Remote. + * @memberof snacktime.app.settings + * @interface IRemote + * @property {string|null} [mediaServerAddress] Remote mediaServerAddress + * @property {boolean|null} [isOnline] Remote isOnline + */ + + /** + * Constructs a new Remote. + * @memberof snacktime.app.settings + * @classdesc Represents a Remote. + * @implements IRemote + * @constructor + * @param {snacktime.app.settings.IRemote=} [properties] Properties to set + */ + function Remote(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } /** - * Settings mediaServerAddress. + * Remote mediaServerAddress. * @member {string} mediaServerAddress - * @memberof snacktime.app.settings.Settings + * @memberof snacktime.app.settings.Remote * @instance */ - Settings.prototype.mediaServerAddress = ""; + Remote.prototype.mediaServerAddress = ""; - return Settings; + /** + * Remote isOnline. + * @member {boolean} isOnline + * @memberof snacktime.app.settings.Remote + * @instance + */ + Remote.prototype.isOnline = false; + + return Remote; })(); return settings; @@ -1462,6 +1553,136 @@ export const snacktime = $root.snacktime = (() => { return app; })(); + snacktime.status = (function() { + + /** + * Namespace status. + * @memberof snacktime + * @namespace + */ + const status = {}; + + status.service = (function() { + + /** + * Namespace service. + * @memberof snacktime.status + * @namespace + */ + const service = {}; + + service.PingRequest = (function() { + + /** + * Properties of a PingRequest. + * @memberof snacktime.status.service + * @interface IPingRequest + */ + + /** + * Constructs a new PingRequest. + * @memberof snacktime.status.service + * @classdesc Represents a PingRequest. + * @implements IPingRequest + * @constructor + * @param {snacktime.status.service.IPingRequest=} [properties] Properties to set + */ + function PingRequest(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + return PingRequest; + })(); + + service.PingResponse = (function() { + + /** + * Properties of a PingResponse. + * @memberof snacktime.status.service + * @interface IPingResponse + */ + + /** + * Constructs a new PingResponse. + * @memberof snacktime.status.service + * @classdesc Represents a PingResponse. + * @implements IPingResponse + * @constructor + * @param {snacktime.status.service.IPingResponse=} [properties] Properties to set + */ + function PingResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + return PingResponse; + })(); + + service.Status = (function() { + + /** + * Constructs a new Status service. + * @memberof snacktime.status.service + * @classdesc Represents a Status + * @extends $protobuf.rpc.Service + * @constructor + * @param {$protobuf.RPCImpl} rpcImpl RPC implementation + * @param {boolean} [requestDelimited=false] Whether requests are length-delimited + * @param {boolean} [responseDelimited=false] Whether responses are length-delimited + */ + function Status(rpcImpl, requestDelimited, responseDelimited) { + $protobuf.rpc.Service.call(this, rpcImpl, requestDelimited, responseDelimited); + } + + (Status.prototype = Object.create($protobuf.rpc.Service.prototype)).constructor = Status; + + /** + * Callback as used by {@link snacktime.status.service.Status#ping}. + * @memberof snacktime.status.service.Status + * @typedef PingCallback + * @type {function} + * @param {Error|null} error Error, if any + * @param {snacktime.status.service.PingResponse} [response] PingResponse + */ + + /** + * Calls Ping. + * @function ping + * @memberof snacktime.status.service.Status + * @instance + * @param {snacktime.status.service.IPingRequest} request PingRequest message or plain object + * @param {snacktime.status.service.Status.PingCallback} callback Node-style callback called with the error, if any, and PingResponse + * @returns {undefined} + * @variation 1 + */ + Object.defineProperty(Status.prototype.ping = function ping(request, callback) { + return this.rpcCall(ping, $root.snacktime.status.service.PingRequest, $root.snacktime.status.service.PingResponse, request, callback); + }, "name", { value: "Ping" }); + + /** + * Calls Ping. + * @function ping + * @memberof snacktime.status.service.Status + * @instance + * @param {snacktime.status.service.IPingRequest} request PingRequest message or plain object + * @returns {Promise} Promise + * @variation 2 + */ + + return Status; + })(); + + return service; + })(); + + return status; + })(); + snacktime.storage = (function() { /** diff --git a/app/src/views/Settings.vue b/app/src/views/Settings.vue index f4153a6..185820d 100644 --- a/app/src/views/Settings.vue +++ b/app/src/views/Settings.vue @@ -90,7 +90,7 @@
@@ -117,26 +117,52 @@ export default class Settings extends Vue { private mpvPath: string = ""; private svpPath: string = ""; private mediaLocation: string = ""; + private isOnline: boolean = false; async mounted() { let res = await HttpClient.get(Endpoints.SaveSettings()); - this.storagePath = res.payload.fileDir; - this.storagePathTemp = res.payload.tempFileDir; - this.mpvPath = res.payload.mpvPath; - this.svpPath = res.payload.svpPath; - this.mediaLocation = res.payload.mediaServerAddress; + this.storagePath = + res.payload.system && res.payload.system.fileDir + ? res.payload.system.fileDir + : ""; + this.storagePathTemp = + res.payload.system && res.payload.system.tempFileDir + ? res.payload.system.tempFileDir + : ""; + this.mpvPath = + res.payload.system && res.payload.system.mpvPath + ? res.payload.system.mpvPath + : ""; + this.svpPath = + res.payload.system && res.payload.system.svpPath + ? res.payload.system.svpPath + : ""; + this.mediaLocation = + res.payload.remote && res.payload.remote.mediaServerAddress + ? res.payload.remote.mediaServerAddress + : ""; + this.isOnline = + res.payload.remote && res.payload.remote.isOnline + ? res.payload.remote.isOnline + : false; } async save(): Promise { let payload = { - fileDir: this.storagePath, - tempFileDir: this.storagePathTemp, - mpvPath: this.mpvPath, - svpPath: this.svpPath, - mediaServerAddress: this.mediaLocation + system: { + fileDir: this.storagePath, + tempFileDir: this.storagePathTemp, + mpvPath: this.mpvPath, + svpPath: this.svpPath + }, + remote: { + isOnline: this.isOnline, + mediaServerAddress: this.mediaLocation + } } as snackTimeSettings; + console.log(payload); await HttpClient.post(Endpoints.SaveSettings(), payload); } }