diff --git a/Aurora.test/Aurora.test.csproj b/Aurora.test/Aurora.test.csproj index 8aafe1a..6c6b85c 100644 --- a/Aurora.test/Aurora.test.csproj +++ b/Aurora.test/Aurora.test.csproj @@ -22,4 +22,96 @@ + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + \ No newline at end of file diff --git a/Aurora.test/ControllerTests/MediaControllerTest.cs b/Aurora.test/ControllerTests/MediaControllerTest.cs index 902b672..0b296fe 100644 --- a/Aurora.test/ControllerTests/MediaControllerTest.cs +++ b/Aurora.test/ControllerTests/MediaControllerTest.cs @@ -1,9 +1,14 @@ using NUnit.Framework; using Aurora.Proto.PartyV2; using Aurora.Services.Server; +using Aurora.Services.Library; +using Aurora.Services.Settings; +using Aurora.test.Models.Mock; using Grpc.Core; using System.Threading.Tasks; using System.Linq; +using System.IO; +using Autofac; namespace Aurora.test.ControllerTests { @@ -11,10 +16,35 @@ namespace Aurora.test.ControllerTests { private RemotePartyService.RemotePartyServiceClient _remotePartyService; private Channel _channel; + private IContainer _container; + private IServerService _serverService; + + [OneTimeSetUp] + public void SetupOneTime() + { + ContainerBuilder builder = new ContainerBuilder(); + builder.RegisterType().As().SingleInstance(); + builder.RegisterInstance(new SettingsServiceMock() + { + Username = "Test User 1", + DefaultPort = 4005, + LibraryLocation = string.Format("{0}/Resources", Directory.GetCurrentDirectory()) + }).SingleInstance(); + builder.RegisterType().As().SingleInstance(); + _container = builder.Build(); + } + + [OneTimeTearDown] + public void TearDownOneTime() + { + _container.Dispose(); + } + [SetUp] public void Setup() { - ServerService.Instance.Start("testParty", "asdf"); + _serverService = _container.Resolve(); + _serverService.Start("testParty", "asdf"); _channel = new Channel(string.Format("{0}:{1}", ServerService.GetLocalIPAddress(), 8080), ChannelCredentials.Insecure); _remotePartyService = new RemotePartyService.RemotePartyServiceClient(_channel); } @@ -22,8 +52,22 @@ namespace Aurora.test.ControllerTests [TearDown] public async Task TearDown() { - await ServerService.Instance.Stop(); + await _serverService.Stop(); await _channel.ShutdownAsync(); } + + [Test] + public void TestNotEmpty() + { + ListMediaResponse resp = _remotePartyService.ListMedia(new ListMediaRequest() + { + Parent = "testParty", + PageSize = 5 + }); + + Assert.NotNull(resp.Media); + Assert.NotZero(resp.Media.Count); + Assert.AreEqual(resp.Media.Count, 5); + } } } \ No newline at end of file diff --git a/Aurora.test/ControllerTests/MembersControllerTest.cs b/Aurora.test/ControllerTests/MembersControllerTest.cs index 0671801..a74a184 100644 --- a/Aurora.test/ControllerTests/MembersControllerTest.cs +++ b/Aurora.test/ControllerTests/MembersControllerTest.cs @@ -1,9 +1,14 @@ using NUnit.Framework; using Aurora.Proto.PartyV2; using Aurora.Services.Server; +using Aurora.Services.Library; +using Aurora.Services.Settings; +using Aurora.test.Models.Mock; using Grpc.Core; using System.Threading.Tasks; using System.Linq; +using System.IO; +using Autofac; namespace Aurora.test.ControllerTests { @@ -11,10 +16,36 @@ namespace Aurora.test.ControllerTests { private RemotePartyService.RemotePartyServiceClient _remotePartyService; private Channel _channel; + + private IContainer _container; + private IServerService _serverService; + + [OneTimeSetUp] + public void SetupOneTime() + { + ContainerBuilder builder = new ContainerBuilder(); + builder.RegisterType().As().SingleInstance(); + builder.RegisterInstance(new SettingsServiceMock() + { + Username = "Test User 1", + DefaultPort = 4005, + LibraryLocation = string.Format("{0}/Resource", Directory.GetCurrentDirectory()) + }).SingleInstance(); + builder.RegisterType().As().SingleInstance(); + _container = builder.Build(); + } + + [OneTimeTearDown] + public void TearDownOneTime() + { + _container.Dispose(); + } + [SetUp] public void Setup() { - ServerService.Instance.Start("testParty", "asdf"); + _serverService = _container.Resolve(); + _serverService.Start("testParty", "asdf"); _channel = new Channel(string.Format("{0}:{1}", ServerService.GetLocalIPAddress(), 8080), ChannelCredentials.Insecure); _remotePartyService = new RemotePartyService.RemotePartyServiceClient(_channel); } @@ -22,7 +53,7 @@ namespace Aurora.test.ControllerTests [TearDown] public async Task TearDown() { - await ServerService.Instance.Stop(); + await _serverService.Stop(); await _channel.ShutdownAsync(); } diff --git a/Aurora.test/ControllerTests/PartyControllerTest.cs b/Aurora.test/ControllerTests/PartyControllerTest.cs index 0f4c5df..fbbb61b 100644 --- a/Aurora.test/ControllerTests/PartyControllerTest.cs +++ b/Aurora.test/ControllerTests/PartyControllerTest.cs @@ -1,8 +1,13 @@ using System.Threading.Tasks; +using System.IO; using NUnit.Framework; using Aurora.Proto.PartyV2; using Aurora.Services.Server; +using Aurora.Services.Library; +using Aurora.Services.Settings; +using Aurora.test.Models.Mock; using Grpc.Core; +using Autofac; namespace Aurora.test.ControllerTests { @@ -10,10 +15,35 @@ namespace Aurora.test.ControllerTests { private RemotePartyService.RemotePartyServiceClient _remotePartyService; private Channel _channel; + private IContainer _container; + private IServerService _serverService; + + [OneTimeSetUp] + public void SetupOneTime() + { + ContainerBuilder builder = new ContainerBuilder(); + builder.RegisterType().As().SingleInstance(); + builder.RegisterInstance(new SettingsServiceMock() + { + Username = "Test User 1", + DefaultPort = 4005, + LibraryLocation = string.Format("{0}/Resource", Directory.GetCurrentDirectory()) + }).SingleInstance(); + builder.RegisterType().As().SingleInstance(); + _container = builder.Build(); + } + + [OneTimeTearDown] + public void TearDownOneTime() + { + _container.Dispose(); + } + [SetUp] public void Setup() { - ServerService.Instance.Start("testParty", "asdf"); + _serverService = _container.Resolve(); + _serverService.Start("testParty", "asdf"); _channel = new Channel(string.Format("{0}:{1}", ServerService.GetLocalIPAddress(), 8080), ChannelCredentials.Insecure); _remotePartyService = new RemotePartyService.RemotePartyServiceClient(_channel); } @@ -21,7 +51,7 @@ namespace Aurora.test.ControllerTests [TearDown] public async Task TearDown() { - await ServerService.Instance.Stop(); + await _serverService.Stop(); await _channel.ShutdownAsync(); } diff --git a/Aurora.test/Models/Mock/SettingsServiceMock.cs b/Aurora.test/Models/Mock/SettingsServiceMock.cs new file mode 100644 index 0000000..bcc3c08 --- /dev/null +++ b/Aurora.test/Models/Mock/SettingsServiceMock.cs @@ -0,0 +1,35 @@ +using Aurora.Services.Settings; +using Plugin.Settings.Abstractions; + +namespace Aurora.test.Models.Mock +{ + public class SettingsServiceMock : ISettingsService + { + public SettingsServiceMock() + { + + } + + public ISettings AppSettings { get; set; } + + /// + /// The user's username. This is persisted. + /// + /// + public string Username { get; set; } + + /// + /// The default port to use. This is persisted. + /// + /// + public int DefaultPort { get; set; } + + /// + /// The current sessions clientId. This is assigned by the server. This is not persisted. + /// + /// + public string ClientId { get; set; } + + public string LibraryLocation { get; set; } + } +} \ No newline at end of file diff --git a/Aurora.test/Resources/Jidenna/The Chief/01 A Bull's Tale.mp3 b/Aurora.test/Resources/Jidenna/The Chief/01 A Bull's Tale.mp3 new file mode 100755 index 0000000..4378585 Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/01 A Bull's Tale.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/02 Chief Don't Run.mp3 b/Aurora.test/Resources/Jidenna/The Chief/02 Chief Don't Run.mp3 new file mode 100755 index 0000000..dc40b81 Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/02 Chief Don't Run.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/03 Trampoline.mp3 b/Aurora.test/Resources/Jidenna/The Chief/03 Trampoline.mp3 new file mode 100755 index 0000000..dea9b1f Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/03 Trampoline.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/04 Bambi.mp3 b/Aurora.test/Resources/Jidenna/The Chief/04 Bambi.mp3 new file mode 100755 index 0000000..0ea6edd Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/04 Bambi.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/05 Helicopters _ Beware.mp3 b/Aurora.test/Resources/Jidenna/The Chief/05 Helicopters _ Beware.mp3 new file mode 100755 index 0000000..457fe3f Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/05 Helicopters _ Beware.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/06 Long Live The Chief.mp3 b/Aurora.test/Resources/Jidenna/The Chief/06 Long Live The Chief.mp3 new file mode 100755 index 0000000..04ff67d Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/06 Long Live The Chief.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/07 2 Points.mp3 b/Aurora.test/Resources/Jidenna/The Chief/07 2 Points.mp3 new file mode 100755 index 0000000..6501991 Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/07 2 Points.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/08 The Let Out.mp3 b/Aurora.test/Resources/Jidenna/The Chief/08 The Let Out.mp3 new file mode 100755 index 0000000..9509e2d Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/08 The Let Out.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/09 Safari.mp3 b/Aurora.test/Resources/Jidenna/The Chief/09 Safari.mp3 new file mode 100755 index 0000000..64a4e6c Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/09 Safari.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/10 Adaora.mp3 b/Aurora.test/Resources/Jidenna/The Chief/10 Adaora.mp3 new file mode 100755 index 0000000..22d0f69 Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/10 Adaora.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/11 Little Bit More.mp3 b/Aurora.test/Resources/Jidenna/The Chief/11 Little Bit More.mp3 new file mode 100755 index 0000000..7cf9c19 Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/11 Little Bit More.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/12 Some Kind Of Way.mp3 b/Aurora.test/Resources/Jidenna/The Chief/12 Some Kind Of Way.mp3 new file mode 100755 index 0000000..1b81852 Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/12 Some Kind Of Way.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/13 White Niggas.mp3 b/Aurora.test/Resources/Jidenna/The Chief/13 White Niggas.mp3 new file mode 100755 index 0000000..ccf5195 Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/13 White Niggas.mp3 differ diff --git a/Aurora.test/Resources/Jidenna/The Chief/14 Bully Of The Earth.mp3 b/Aurora.test/Resources/Jidenna/The Chief/14 Bully Of The Earth.mp3 new file mode 100755 index 0000000..784ef6f Binary files /dev/null and b/Aurora.test/Resources/Jidenna/The Chief/14 Bully Of The Earth.mp3 differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/01 Best Day Ever (Prod. By_ ID Labs).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/01 Best Day Ever (Prod. By_ ID Labs).m4a new file mode 100755 index 0000000..5c002a1 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/01 Best Day Ever (Prod. By_ ID Labs).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/02 Get Up (Prod. By_ Teddy Roxpin).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/02 Get Up (Prod. By_ Teddy Roxpin).m4a new file mode 100755 index 0000000..96fbcb3 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/02 Get Up (Prod. By_ Teddy Roxpin).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/03 Donald Trump (Prod. By_ Sap).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/03 Donald Trump (Prod. By_ Sap).m4a new file mode 100755 index 0000000..5ad4e13 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/03 Donald Trump (Prod. By_ Sap).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/04 Oy Vey (Prod By_ ID Labs).mp3 b/Aurora.test/Resources/Mac Miller/Best Day Ever/04 Oy Vey (Prod By_ ID Labs).mp3 new file mode 100755 index 0000000..c758aa5 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/04 Oy Vey (Prod By_ ID Labs).mp3 differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/05 I'll Be There (feat. Phonte) (Prod. By_ Beanz 'n' Kornbread).mp3 b/Aurora.test/Resources/Mac Miller/Best Day Ever/05 I'll Be There (feat. Phonte) (Prod. By_ Beanz 'n' Kornbread).mp3 new file mode 100755 index 0000000..1edcf91 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/05 I'll Be There (feat. Phonte) (Prod. By_ Beanz 'n' Kornbread).mp3 differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/06 Wear My Hat (Prod. By_ Chuck Inglish).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/06 Wear My Hat (Prod. By_ Chuck Inglish).m4a new file mode 100755 index 0000000..5410711 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/06 Wear My Hat (Prod. By_ Chuck Inglish).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/07 Wake Up (Prod By_ Sap & ID Labs).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/07 Wake Up (Prod By_ Sap & ID Labs).m4a new file mode 100755 index 0000000..8e94ac6 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/07 Wake Up (Prod By_ Sap & ID Labs).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/08 All Around The World (Prod. By_ Just Blaze).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/08 All Around The World (Prod. By_ Just Blaze).m4a new file mode 100755 index 0000000..c2cfe88 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/08 All Around The World (Prod. By_ Just Blaze).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/09 Down The Rabbit Hole (Prod. By_ Blue of The Sore Losers).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/09 Down The Rabbit Hole (Prod. By_ Blue of The Sore Losers).m4a new file mode 100755 index 0000000..85ccc30 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/09 Down The Rabbit Hole (Prod. By_ Blue of The Sore Losers).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/10 In The Air (Prod By_ Ritz Reynolds).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/10 In The Air (Prod By_ Ritz Reynolds).m4a new file mode 100755 index 0000000..96f324e Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/10 In The Air (Prod By_ Ritz Reynolds).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/11 Play Ya Cards (Prod By_ Chuck Inglish).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/11 Play Ya Cards (Prod By_ Chuck Inglish).m4a new file mode 100755 index 0000000..b8694c5 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/11 Play Ya Cards (Prod By_ Chuck Inglish).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/12 She Said (Prod By_ Khrysis).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/12 She Said (Prod By_ Khrysis).m4a new file mode 100755 index 0000000..d1917d7 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/12 She Said (Prod By_ Khrysis).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/13 Life Ain't Easy (Prod. By_ ID Labs).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/13 Life Ain't Easy (Prod. By_ ID Labs).m4a new file mode 100755 index 0000000..afa0d89 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/13 Life Ain't Easy (Prod. By_ ID Labs).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/14 Snooze (Prod By_ ID Labs).m4a b/Aurora.test/Resources/Mac Miller/Best Day Ever/14 Snooze (Prod By_ ID Labs).m4a new file mode 100755 index 0000000..f1573a8 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/14 Snooze (Prod By_ ID Labs).m4a differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/15 Keep Floatin' (feat. Wiz Khalifa) (Prod. By_ ID Labs).mp3 b/Aurora.test/Resources/Mac Miller/Best Day Ever/15 Keep Floatin' (feat. Wiz Khalifa) (Prod. By_ ID Labs).mp3 new file mode 100755 index 0000000..c813526 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/15 Keep Floatin' (feat. Wiz Khalifa) (Prod. By_ ID Labs).mp3 differ diff --git a/Aurora.test/Resources/Mac Miller/Best Day Ever/16 BDE Bonus (Prod. By_ ID Labs).mp3 b/Aurora.test/Resources/Mac Miller/Best Day Ever/16 BDE Bonus (Prod. By_ ID Labs).mp3 new file mode 100755 index 0000000..1eb1a11 Binary files /dev/null and b/Aurora.test/Resources/Mac Miller/Best Day Ever/16 BDE Bonus (Prod. By_ ID Labs).mp3 differ diff --git a/Aurora/App.xaml.cs b/Aurora/App.xaml.cs index ca655b9..33e3757 100644 --- a/Aurora/App.xaml.cs +++ b/Aurora/App.xaml.cs @@ -12,6 +12,7 @@ using LibVLCSharp.Shared; using Xamarin.Forms; using Aurora.Services.Player; using Aurora.Services.Settings; +using Aurora.Services.Library; namespace Aurora { @@ -29,6 +30,7 @@ namespace Aurora _builder.RegisterType().As().SingleInstance(); _builder.RegisterType().As().SingleInstance(); _builder.RegisterType().As().SingleInstance(); + _builder.RegisterType().As().SingleInstance(); _builder.RegisterType().SingleInstance(); _builder.RegisterType(); _builder.RegisterType(); diff --git a/Aurora/Design/Views/Profile/ProfileView.xaml b/Aurora/Design/Views/Profile/ProfileView.xaml index 58bdbf2..a2fd09d 100644 --- a/Aurora/Design/Views/Profile/ProfileView.xaml +++ b/Aurora/Design/Views/Profile/ProfileView.xaml @@ -22,6 +22,14 @@ + + \ No newline at end of file diff --git a/Aurora/Design/Views/Profile/ProfileViewModel.cs b/Aurora/Design/Views/Profile/ProfileViewModel.cs index ac86be5..be75ad2 100644 --- a/Aurora/Design/Views/Profile/ProfileViewModel.cs +++ b/Aurora/Design/Views/Profile/ProfileViewModel.cs @@ -32,5 +32,15 @@ namespace Aurora.Design.Views.Profile OnPropertyChanged("Port"); } } + + public string LibraryPath + { + get { return this._settingsService.LibraryLocation; } + set + { + this._settingsService.LibraryLocation = value; + OnPropertyChanged("LibraryPath"); + } + } } } diff --git a/Aurora/Design/Views/Songs/SongsViewModel.cs b/Aurora/Design/Views/Songs/SongsViewModel.cs index 588f0e4..b651342 100644 --- a/Aurora/Design/Views/Songs/SongsViewModel.cs +++ b/Aurora/Design/Views/Songs/SongsViewModel.cs @@ -1,6 +1,6 @@ using System.Collections.ObjectModel; using Aurora.Models.Media; -using Aurora.Services; +using Aurora.Services.Library; using Xamarin.Forms; namespace Aurora.Design.Views.Songs @@ -10,15 +10,18 @@ namespace Aurora.Design.Views.Songs #region Fields private ObservableCollection _songsList; private BaseMedia _selectedSong; + private ILibraryService _libraryService; #endregion Fields #region Constructor - public SongsViewModel() + public SongsViewModel(ILibraryService libraryService) { _songsList = new ObservableCollection(); DoubleClickCommand = new Command(OnDoubleClickExecute, OnDoubleClickCanExecute); + this._libraryService = libraryService; + Initialize(); } @@ -45,7 +48,7 @@ namespace Aurora.Design.Views.Songs public void Initialize() { - SongsList = LibraryService.Instance.GetLibrary(); + SongsList = this._libraryService.GetLibrary(); } #endregion Methods diff --git a/Aurora/Models/Media/BaseMedia.cs b/Aurora/Models/Media/BaseMedia.cs index c3a22e8..474186d 100644 --- a/Aurora/Models/Media/BaseMedia.cs +++ b/Aurora/Models/Media/BaseMedia.cs @@ -10,6 +10,7 @@ namespace Aurora.Models.Media public BaseMedia() { + //TODO need to make sure this is unique Id = Guid.NewGuid().ToString(); } diff --git a/Aurora/Proto/party.v2.proto b/Aurora/Proto/party.v2.proto index 3b7532d..175a219 100644 --- a/Aurora/Proto/party.v2.proto +++ b/Aurora/Proto/party.v2.proto @@ -239,8 +239,6 @@ message MemberDeletedEvent { } message EventSubscription { - //Resource name of the event - string name = 1; EventType type = 2; } @@ -253,7 +251,6 @@ message ListEventSubscriptionsRequest { message ListEventSubscriptionsResponse { repeated EventSubscription subscriptions = 1; - string nextPageToken = 3; } message CreateEventSubscriptionRequest { @@ -264,7 +261,8 @@ message CreateEventSubscriptionRequest { message DeleteEventSubscriptionRequest { //Resource name of the subscription to delete - string name = 1; + string parent = 1; + EventType type = 2; } message DeleteAllEventSubscriptionsRequest { diff --git a/Aurora/RemoteImpl/RemotePartyImpl.cs b/Aurora/RemoteImpl/RemotePartyImpl.cs index b9bd630..afb15b4 100644 --- a/Aurora/RemoteImpl/RemotePartyImpl.cs +++ b/Aurora/RemoteImpl/RemotePartyImpl.cs @@ -6,8 +6,9 @@ using Aurora.Utils; using Aurora.Proto.Party; using Aurora.Proto.Events; using Aurora.Services.EventManager; -using Aurora.Services; using Aurora.Models.Media; +using Aurora.Services.Library; +using Autofac; namespace Aurora.RemoteImpl { @@ -90,49 +91,56 @@ namespace Aurora.RemoteImpl public override Task GetQueue(Proto.General.Empty empty, Grpc.Core.ServerCallContext context) { + QueueResponse mediaList = new QueueResponse(); + //This will change as queuing operation gets solidified //Simply return the hosts library - - ObservableCollection queue = LibraryService.Instance.GetLibrary(); - - QueueResponse mediaList = new QueueResponse(); - foreach (BaseMedia media in queue) + using (var scope = App.Container.BeginLifetimeScope()) { - AudioMetadata metadata = new AudioMetadata(); - try + ILibraryService library = scope.Resolve(); + + ObservableCollection queue = library.GetLibrary(); + + + foreach (BaseMedia media in queue) { - if (media.Metadata is AudioMetadata) + AudioMetadata metadata = new AudioMetadata(); + try { - metadata = media.Metadata as AudioMetadata; + if (media.Metadata is AudioMetadata) + { + metadata = media.Metadata as AudioMetadata; - RemoteMediaData data = new RemoteMediaData(); - data.Id = media.Id; - if (metadata.Title != null) - { - data.Title = metadata.Title; - } - if (metadata.Artist != null) - { - data.Artist = metadata.Artist; - } - if (metadata.Album != null) - { - data.Album = metadata.Album; - } - if (metadata.Duration != null) - { - data.Duration = metadata.Duration; - } + RemoteMediaData data = new RemoteMediaData(); + data.Id = media.Id; + if (metadata.Title != null) + { + data.Title = metadata.Title; + } + if (metadata.Artist != null) + { + data.Artist = metadata.Artist; + } + if (metadata.Album != null) + { + data.Album = metadata.Album; + } + if (metadata.Duration != null) + { + data.Duration = metadata.Duration; + } - mediaList.MediaList.Add(data); + mediaList.MediaList.Add(data); + } + } + catch (Exception ex) + { + Console.WriteLine(string.Format("Error preparing queue: {0}", ex.Message)); } } - catch (Exception ex) - { - Console.WriteLine(string.Format("Error preparing queue: {0}", ex.Message)); - } } + return Task.FromResult(mediaList); } diff --git a/Aurora/RemoteImpl/RemotePlaybackImpl.cs b/Aurora/RemoteImpl/RemotePlaybackImpl.cs index 17da449..9d554e8 100644 --- a/Aurora/RemoteImpl/RemotePlaybackImpl.cs +++ b/Aurora/RemoteImpl/RemotePlaybackImpl.cs @@ -1,11 +1,10 @@ using System; using System.Threading.Tasks; -using System.Threading; -using System.Collections.Generic; -using Aurora.Services; using Aurora.Proto.Playback; using Aurora.Proto.General; using Aurora.Models.Media; +using Aurora.Services.Library; +using Autofac; namespace Aurora.RemoteImpl { @@ -15,38 +14,44 @@ namespace Aurora.RemoteImpl Grpc.Core.IServerStreamWriter responseStream, Grpc.Core.ServerCallContext context) { - BaseMedia originalSong = LibraryService.Instance.GetSong(request.Id); - if (!(originalSong is LocalAudio)) + using (var scope = App.Container.BeginLifetimeScope()) { - return; - } + ILibraryService library = scope.Resolve(); - //Copy media object to not interfere with other threads - LocalAudio songCopy = new LocalAudio((LocalAudio)originalSong); - - try - { - //Load only if not already loaded. (Multiple clients may be requesting media) - if (!songCopy.IsLoaded) + BaseMedia originalSong = library.GetSong(request.Id); + if (!(originalSong is LocalAudio)) { - await songCopy.Load(); + return; } - //Send stream - Console.WriteLine("Begin sending file"); - byte[] buffer = new byte[2048]; // read in chunks of 2KB - int bytesRead; - while ((bytesRead = songCopy.DataStream.Read(buffer, 0, buffer.Length)) > 0) + //Copy media object to not interfere with other threads + LocalAudio songCopy = new LocalAudio((LocalAudio)originalSong); + + try { - Google.Protobuf.ByteString bufferByteString = Google.Protobuf.ByteString.CopyFrom(buffer); - await responseStream.WriteAsync(new Chunk { Content = bufferByteString }); + //Load only if not already loaded. (Multiple clients may be requesting media) + if (!songCopy.IsLoaded) + { + await songCopy.Load(); + } + + //Send stream + Console.WriteLine("Begin sending file"); + byte[] buffer = new byte[2048]; // read in chunks of 2KB + int bytesRead; + while ((bytesRead = songCopy.DataStream.Read(buffer, 0, buffer.Length)) > 0) + { + Google.Protobuf.ByteString bufferByteString = Google.Protobuf.ByteString.CopyFrom(buffer); + await responseStream.WriteAsync(new Chunk { Content = bufferByteString }); + } + Console.WriteLine("Done sending file"); + } + catch (Exception ex) + { + Console.WriteLine("Exception caught while sending audio file: " + ex.Message); } - Console.WriteLine("Done sending file"); - } - catch (Exception ex) - { - Console.WriteLine("Exception caught while sending audio file: " + ex.Message); } + } } } \ No newline at end of file diff --git a/Aurora/Services/Library/ILibraryService.cs b/Aurora/Services/Library/ILibraryService.cs new file mode 100644 index 0000000..ad67fb9 --- /dev/null +++ b/Aurora/Services/Library/ILibraryService.cs @@ -0,0 +1,12 @@ +using System.Collections.ObjectModel; +using Aurora.Models.Media; + +namespace Aurora.Services.Library +{ + public interface ILibraryService + { + ObservableCollection GetLibrary(); + + BaseMedia GetSong(string Id); + } +} \ No newline at end of file diff --git a/Aurora/Services/LibraryService.cs b/Aurora/Services/Library/LibraryService.cs similarity index 85% rename from Aurora/Services/LibraryService.cs rename to Aurora/Services/Library/LibraryService.cs index fb8dfcf..a0704ec 100644 --- a/Aurora/Services/LibraryService.cs +++ b/Aurora/Services/Library/LibraryService.cs @@ -3,22 +3,24 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using Aurora.Models.Media; +using Aurora.Services.Settings; using Aurora.Utils; -namespace Aurora.Services +namespace Aurora.Services.Library { - public class LibraryService : BaseService + public class LibraryService : ILibraryService { #region Fields - private string _pathName = "/Users/brandonwatson/Music/iTunes/iTunes Media/Music"; + private string _pathName; private string _extensions = ".wav,.mp3,.aiff,.flac,.m4a,.m4b,.wma"; private Dictionary _library; #endregion Fields - public LibraryService() + public LibraryService(ISettingsService settingsService) { _library = new Dictionary(); + this._pathName = settingsService.LibraryLocation; LoadLibrary(); } diff --git a/Aurora/Services/Player/PlayerService.cs b/Aurora/Services/Player/PlayerService.cs index bf85e4e..032c377 100644 --- a/Aurora/Services/Player/PlayerService.cs +++ b/Aurora/Services/Player/PlayerService.cs @@ -9,7 +9,7 @@ using LibVLCSharp.Shared; namespace Aurora.Services.Player { - public class PlayerService : BaseService, IPlayer + public class PlayerService : IPlayer { private const long _ticksPerMillisecond = 10000; private BaseMedia _currentMedia; diff --git a/Aurora/Services/Server/Controllers/Constructor.cs b/Aurora/Services/Server/Controllers/Constructor.cs index 5bdb63c..960d65f 100644 --- a/Aurora/Services/Server/Controllers/Constructor.cs +++ b/Aurora/Services/Server/Controllers/Constructor.cs @@ -1,22 +1,29 @@ using System; -using System.Threading.Tasks; +using System.Collections.ObjectModel; using System.Collections.Generic; using Aurora.Proto.PartyV2; +using Aurora.Services.Library; +using Aurora.Models.Media; +using Autofac; namespace Aurora.Services.Server.Controllers { public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase { + private ILibraryService _libraryService; + /// /// Constructor for partial class /// - public RemotePartyController(string partyName, string description) + public RemotePartyController(string partyName, string description, ILibraryService libraryService) { this._startDateTime = DateTime.UtcNow; this._displayName = partyName; this._description = description; this._memberList = new SortedList(); - this._mediaList = new SortedList(); + this._mediaList = new SortedList(); + + _libraryService = libraryService; string userName = "testUser"; @@ -32,7 +39,47 @@ namespace Aurora.Services.Server.Controllers this._memberList.Add(_hostMember.Name, _hostMember); //Add media from library + //This will change as queuing operation gets solidified + //Simply return the hosts library + ObservableCollection queue = _libraryService.GetLibrary(); + + foreach (BaseMedia media in queue) + { + AudioMetadata metadata = new AudioMetadata(); + try + { + if (media.Metadata is AudioMetadata) + { + metadata = media.Metadata as AudioMetadata; + + Media data = new Media(); + data.Name = media.Id; + if (metadata.Title != null) + { + data.Title = metadata.Title; + } + if (metadata.Artist != null) + { + data.Artist = metadata.Artist; + } + if (metadata.Album != null) + { + data.Album = metadata.Album; + } + if (metadata.Duration != null) + { + data.Duration = metadata.Duration; + } + + _mediaList.Add(data.Name, data); + } + } + catch (Exception ex) + { + Console.WriteLine(string.Format("Error preparing queue: {0}", ex.Message)); + } + } } } } \ No newline at end of file diff --git a/Aurora/Services/Server/Controllers/EventController.cs b/Aurora/Services/Server/Controllers/EventController.cs index 399312c..29fec14 100644 --- a/Aurora/Services/Server/Controllers/EventController.cs +++ b/Aurora/Services/Server/Controllers/EventController.cs @@ -1,6 +1,8 @@ using System; using System.Threading.Tasks; +using System.Threading; using Aurora.Proto.PartyV2; +using Aurora.Utils; namespace Aurora.Services.Server.Controllers { @@ -8,7 +10,26 @@ namespace Aurora.Services.Server.Controllers { public override Task GetEvents(GetEventsRequest request, Grpc.Core.IServerStreamWriter responseStream, Grpc.Core.ServerCallContext context) { - throw new NotImplementedException(); + string peerId = Misc.Combine(new string[] { context.Peer, request.Parent }); + Console.WriteLine(string.Format("SERVER - Events request received from peer: {0}", peerId)); + + AutoResetEvent are = new AutoResetEvent(false); + Action callback = (BaseEvent bEvent) => + { + Console.WriteLine(string.Format("SERVER - Event fired for peer: {0}", peerId)); + //TODO need to remove callback if stream no longer exists IE. Client crashed or stopped + responseStream.WriteAsync(bEvent); + + }; + + Action cancelled = () => + { + are.Set(); + }; + + this._eventManager.AddEventHandler(callback, cancelled, Misc.Combine(new string[] { context.Peer, request.Parent })); + are.WaitOne(); + return Task.FromResult(null); } } } \ No newline at end of file diff --git a/Aurora/Services/Server/Controllers/EventSubscriptionController.cs b/Aurora/Services/Server/Controllers/EventSubscriptionController.cs index d934bfd..d78dd7c 100644 --- a/Aurora/Services/Server/Controllers/EventSubscriptionController.cs +++ b/Aurora/Services/Server/Controllers/EventSubscriptionController.cs @@ -2,6 +2,7 @@ using System; using System.Threading.Tasks; using Aurora.Proto.PartyV2; using Aurora.Proto.General; +using Aurora.Utils; namespace Aurora.Services.Server.Controllers { @@ -14,17 +15,24 @@ namespace Aurora.Services.Server.Controllers public override Task CreateEventSubscription(CreateEventSubscriptionRequest request, Grpc.Core.ServerCallContext context) { - throw new NotImplementedException(); + Console.WriteLine(string.Format("SERVER - Subscription from client with id: {0}", request.Parent)); + this._eventManager.AddSubscription(Misc.Combine(new string[] { context.Peer, request.Parent }), request.EventSubscription.Type); + + return Task.FromResult(request.EventSubscription); } public override Task DeleteEventSubscription(DeleteEventSubscriptionRequest request, Grpc.Core.ServerCallContext context) { - throw new NotImplementedException(); + this._eventManager.RemoveSubscription(Misc.Combine(new string[] { context.Peer, request.Parent }), request.Type); + + return Task.FromResult(new Empty()); } public override Task DeleteAllEventSubscriptions(DeleteAllEventSubscriptionsRequest request, Grpc.Core.ServerCallContext context) { - throw new NotImplementedException(); + this._eventManager.RemoveAllSubscriptions(Misc.Combine(new string[] { context.Peer, request.Parent })); + + return Task.FromResult(new Empty()); } } } \ No newline at end of file diff --git a/Aurora/Services/Server/Controllers/MediaController.cs b/Aurora/Services/Server/Controllers/MediaController.cs index cb35f5b..0e7d2e8 100644 --- a/Aurora/Services/Server/Controllers/MediaController.cs +++ b/Aurora/Services/Server/Controllers/MediaController.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Aurora.Proto.PartyV2; using Aurora.Models.Media; using Aurora.Proto.General; +using Aurora.Services.Library; using Aurora.Services.Player; using Autofac; @@ -11,7 +12,7 @@ namespace Aurora.Services.Server.Controllers { public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase { - private SortedList _mediaList; + private SortedList _mediaList; public override Task ListMedia(ListMediaRequest request, Grpc.Core.ServerCallContext context) { @@ -31,22 +32,8 @@ namespace Aurora.Services.Server.Controllers } //Gather page - List baseMedia = new List(_mediaList.Values); - foreach (BaseMedia media in baseMedia) - { - if (media.Metadata is AudioMetadata) - { - AudioMetadata meta = media.Metadata as AudioMetadata; - resp.Media.Add(new Media() - { - Name = media.Id, - Title = meta.Title, - Album = meta.Album, - Artist = meta.Artist, - Duration = meta.Duration - }); - } - } + List mediaList = new List(_mediaList.Values); + resp.Media.AddRange(mediaList.GetRange(startIdx, pageSize)); resp.NextPageToken = resp.Media[resp.Media.Count - 1].Name; return Task.FromResult(resp); @@ -54,24 +41,14 @@ namespace Aurora.Services.Server.Controllers public override Task GetMedia(GetMediaRequest request, Grpc.Core.ServerCallContext context) { - _mediaList.TryGetValue(request.Name, out BaseMedia baseMedia); + _mediaList.TryGetValue(request.Name, out Media baseMedia); if (baseMedia == null) { throw new KeyNotFoundException(); } - Media media = new Media(); - if (baseMedia.Metadata != null && baseMedia.Metadata is AudioMetadata) - { - AudioMetadata metadata = baseMedia.Metadata as AudioMetadata; - media.Name = baseMedia.Id; - media.Title = metadata.Title; - media.Artist = metadata.Artist; - media.Album = metadata.Album; - } - - return Task.FromResult(media); + return Task.FromResult(baseMedia); } public override Task CreateMedia(CreateMediaRequest request, Grpc.Core.ServerCallContext context) @@ -86,37 +63,43 @@ namespace Aurora.Services.Server.Controllers public override async Task StreamMedia(StreamMediaRequest request, Grpc.Core.IServerStreamWriter responseStream, Grpc.Core.ServerCallContext context) { - BaseMedia originalSong = LibraryService.Instance.GetSong(request.Name); - if (!(originalSong is LocalAudio)) + using (var scope = App.Container.BeginLifetimeScope()) { - return; - } + ILibraryService library = scope.Resolve(); - //Copy media object to not interfere with other threads - LocalAudio songCopy = new LocalAudio((LocalAudio)originalSong); - - try - { - //Load only if not already loaded. (Multiple clients may be requesting media) - if (!songCopy.IsLoaded) + BaseMedia originalSong = library.GetSong(request.Name); + if (!(originalSong is LocalAudio)) { - await songCopy.Load(); + return; } - //Send stream - Console.WriteLine("Begin sending file"); - byte[] buffer = new byte[2048]; // read in chunks of 2KB - int bytesRead; - while ((bytesRead = songCopy.DataStream.Read(buffer, 0, buffer.Length)) > 0) + //Copy media object to not interfere with other threads + LocalAudio songCopy = new LocalAudio((LocalAudio)originalSong); + + try { - Google.Protobuf.ByteString bufferByteString = Google.Protobuf.ByteString.CopyFrom(buffer); - await responseStream.WriteAsync(new Chunk { Content = bufferByteString }); + //Load only if not already loaded. (Multiple clients may be requesting media) + if (!songCopy.IsLoaded) + { + await songCopy.Load(); + } + + //Send stream + Console.WriteLine("Begin sending file"); + byte[] buffer = new byte[2048]; // read in chunks of 2KB + int bytesRead; + while ((bytesRead = songCopy.DataStream.Read(buffer, 0, buffer.Length)) > 0) + { + Google.Protobuf.ByteString bufferByteString = Google.Protobuf.ByteString.CopyFrom(buffer); + await responseStream.WriteAsync(new Chunk { Content = bufferByteString }); + } + Console.WriteLine("Done sending file"); } - Console.WriteLine("Done sending file"); - } - catch (Exception ex) - { - Console.WriteLine("Exception caught while sending audio file: " + ex.Message); + catch (Exception ex) + { + Console.WriteLine("Exception caught while sending audio file: " + ex.Message); + } + } } diff --git a/Aurora/Services/Server/Server/IServerService.cs b/Aurora/Services/Server/Server/IServerService.cs new file mode 100644 index 0000000..daf444f --- /dev/null +++ b/Aurora/Services/Server/Server/IServerService.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; + +namespace Aurora.Services.Server +{ + public interface IServerService + { + int Port { get; } + + string Hostname { get; } + + bool Initialized { get; } + + + /// + /// Start Server + /// + void Start(string partyName, string description); + + /// + /// Shutdown server async. + /// + /// Task + Task Stop(); + + Task Reset(); + } +} \ No newline at end of file diff --git a/Aurora/Services/Server/ServerService.cs b/Aurora/Services/Server/Server/ServerService.cs similarity index 92% rename from Aurora/Services/Server/ServerService.cs rename to Aurora/Services/Server/Server/ServerService.cs index 2f21af0..5ce7996 100644 --- a/Aurora/Services/Server/ServerService.cs +++ b/Aurora/Services/Server/Server/ServerService.cs @@ -4,16 +4,18 @@ using System.Net; using System.Net.Sockets; using Grpc.Core; using Aurora.Services.Server.Controllers; +using Aurora.Services.Library; using Aurora.Proto.PartyV2; namespace Aurora.Services.Server { - public class ServerService : BaseService + public class ServerService : IServerService { private int _port = 8080; private string _hostname; private Grpc.Core.Server _server; + private ILibraryService _libraryService; //Implementation class declarations private RemotePartyController _remotePartyController; @@ -21,10 +23,10 @@ namespace Aurora.Services.Server /// /// Constructor. Registers GRPC service implementations. /// - public ServerService() + public ServerService(ILibraryService libraryService) { string host = GetLocalIPAddress(); - + this._libraryService = libraryService; if (string.IsNullOrWhiteSpace(host)) { throw new Exception("This device must have a valid IP address"); @@ -69,7 +71,7 @@ namespace Aurora.Services.Server }; //Construct implementations - _remotePartyController = new RemotePartyController(partyName, description); + _remotePartyController = new RemotePartyController(partyName, description, _libraryService); // Register grpc RemoteService with singleton server service RegisterService(RemotePartyService.BindService(_remotePartyController)); diff --git a/Aurora/Services/Settings/ISettingsService.cs b/Aurora/Services/Settings/ISettingsService.cs index ddb0816..d8b74f3 100644 --- a/Aurora/Services/Settings/ISettingsService.cs +++ b/Aurora/Services/Settings/ISettingsService.cs @@ -23,5 +23,7 @@ namespace Aurora.Services.Settings /// /// string ClientId { get; set; } + + string LibraryLocation { get; set; } } } \ No newline at end of file diff --git a/Aurora/Services/Settings/SettingsService.cs b/Aurora/Services/Settings/SettingsService.cs index 485f63c..48a3617 100644 --- a/Aurora/Services/Settings/SettingsService.cs +++ b/Aurora/Services/Settings/SettingsService.cs @@ -11,6 +11,8 @@ namespace Aurora.Services.Settings private string _usernameKey = "username"; private string _defaultPortKey = "port"; + private string _libraryLocationKey = "libraryLocation"; + public SettingsService() { } @@ -55,6 +57,12 @@ namespace Aurora.Services.Settings set { AppSettings.AddOrUpdateValue(_defaultPortKey, value); } } + public string LibraryLocation + { + get { return AppSettings.GetValueOrDefault(_libraryLocationKey, "~/Music"); } + set { AppSettings.AddOrUpdateValue(_libraryLocationKey, value); } + } + /// /// The current sessions clientId. This is assigned by the server. This is not persisted. ///