diff --git a/samples/Simple/Program.cs b/samples/Simple/Program.cs new file mode 100644 index 0000000..664022c --- /dev/null +++ b/samples/Simple/Program.cs @@ -0,0 +1,71 @@ +using System; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Net.Mime; +using System.Text; +using System.Threading.Tasks; +using Jellyfin.Sdk; +using Microsoft.Extensions.DependencyInjection; + +namespace Simple +{ + internal static class Program + { + private static async Task Main() + { + var serviceProvider = ConfigureServices(); + + // Initialize the sdk client settings. This only needs to happen once on startup. + var sdkClientSettings = serviceProvider.GetRequiredService(); + sdkClientSettings.InitializeClientSettings( + "My-Jellyfin-Client", + "0.0.1", + "Sample Device", + $"this-is-my-device-id-{Guid.NewGuid():N}"); + + var sampleService = serviceProvider.GetRequiredService(); + await sampleService.RunAsync() + .ConfigureAwait(false); + + Console.WriteLine("Sample complete"); + } + + private static ServiceProvider ConfigureServices() + { + var serviceCollection = new ServiceCollection(); + + // Add Http Client + serviceCollection.AddHttpClient("Default", c => + { + c.DefaultRequestHeaders.UserAgent.Add( + new ProductInfoHeaderValue( + "My-Jellyfin-Client", + "0.0.1")); + + c.DefaultRequestHeaders.Accept.Add( + new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json, 1.0)); + c.DefaultRequestHeaders.Accept.Add( + new MediaTypeWithQualityHeaderValue("*/*", 0.8)); + }) + .ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler + { + AutomaticDecompression = DecompressionMethods.All, + RequestHeaderEncodingSelector = (_, _) => Encoding.UTF8 + }); + + // Add Jellyfin SDK services. + serviceCollection + .AddSingleton() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped(); + + // Add sample service + serviceCollection.AddSingleton(); + + return serviceCollection.BuildServiceProvider(); + } + } +} \ No newline at end of file diff --git a/samples/Simple/SampleService.cs b/samples/Simple/SampleService.cs new file mode 100644 index 0000000..0cd915e --- /dev/null +++ b/samples/Simple/SampleService.cs @@ -0,0 +1,136 @@ +using System; +using System.Threading.Tasks; +using Jellyfin.Sdk; +using SystemException = Jellyfin.Sdk.SystemException; + +namespace Simple +{ + /// + /// Sample Jellyfin service. + /// + public class SampleService + { + private readonly SdkClientSettings _sdkClientSettings; + private readonly ISystemClient _systemClient; + private readonly IUserClient _userClient; + private readonly IUserViewsClient _userViewsClient; + + /// + /// Initializes a new instance of the class. + /// + /// Instance of the . + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + public SampleService( + SdkClientSettings sdkClientSettings, + ISystemClient systemClient, + IUserClient userClient, + IUserViewsClient userViewsClient) + { + _sdkClientSettings = sdkClientSettings; + _systemClient = systemClient; + _userClient = userClient; + _userViewsClient = userViewsClient; + } + + /// + /// Run the sample. + /// + /// A representing the asynchronous operation. + public async Task RunAsync() + { + var validServer = false; + do + { + // Prompt for server url. + // Url must be proto://host/path + // ex: https://demo.jellyfin.org/stable + Console.Write("Server Url: "); + var host = Console.ReadLine(); + + _sdkClientSettings.BaseUrl = host; + try + { + // Get public system info to verify that the url points to a Jellyfin server. + var systemInfo = await _systemClient.GetPublicSystemInfoAsync() + .ConfigureAwait(false); + validServer = true; + Console.WriteLine($"Connected to {host}"); + Console.WriteLine($"Server Name: {systemInfo.ServerName}"); + Console.WriteLine($"Server Version: {systemInfo.Version}"); + } + catch (InvalidOperationException ex) + { + Console.Error.WriteLine("Invalid url"); + Console.Error.WriteLine(ex); + } + catch (SystemException ex) + { + Console.Error.WriteLine($"Error connecting to {host}"); + Console.Error.WriteLine(ex); + } + } + while (!validServer); + + var validUser = false; + + UserDto userDto = null!; + do + { + try + { + Console.Write("Username: "); + var username = Console.ReadLine(); + + Console.Write("Password: "); + var password = Console.ReadLine(); + + Console.WriteLine($"Logging into {_sdkClientSettings.BaseUrl}"); + + // Authenticate user. + var authenticationResult = await _userClient.AuthenticateUserByNameAsync(new AuthenticateUserByName + { + Username = username, + Pw = password + }) + .ConfigureAwait(false); + + _sdkClientSettings.AccessToken = authenticationResult.AccessToken; + userDto = authenticationResult.User; + Console.WriteLine("Authentication success."); + Console.WriteLine($"Welcome to Jellyfin - {userDto.Name}"); + validUser = true; + } + catch (UserException ex) + { + Console.Error.WriteLine("Error authenticating."); + Console.Error.WriteLine(ex); + } + } + while (!validUser); + + await PrintViews(userDto.Id) + .ConfigureAwait(false); + } + + private async Task PrintViews(Guid userId) + { + try + { + var views = await _userViewsClient.GetUserViewsAsync(userId) + .ConfigureAwait(false); + Console.WriteLine("Printing Views:"); + foreach (var view in views.Items) + { + Console.WriteLine($"{view.Id} - {view.Name}"); + } + } + catch (UserViewsException ex) + { + Console.Error.WriteLine("Error getting user views"); + Console.Error.WriteLine(ex); + } + } + } +} \ No newline at end of file diff --git a/samples/Simple/Simple.csproj b/samples/Simple/Simple.csproj new file mode 100644 index 0000000..7693b4c --- /dev/null +++ b/samples/Simple/Simple.csproj @@ -0,0 +1,25 @@ + + + + Exe + net5.0 + true + true + enable + AllEnabledByDefault + ..\..\jellyfin.ruleset + + + + + + + + + + + + + + +