/// <summary> /// Initializes a new instance of the <see cref="PascalCaseJsonProfileFormatter"/> class. /// </summary> public PascalCaseJsonProfileFormatter() : base(JsonDefaults.GetPascalCaseOptions()) { SupportedMediaTypes.Clear(); // Add application/json for default formatter SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json")); SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json;profile=\"PascalCase\"")); }
/// <summary> /// Initializes a new instance of the <see cref="Notifier"/> class. /// </summary> /// <param name="logger">Instance of the <see cref="ILogger{Notifier}"/> interface.</param> /// <param name="serverConfiguration">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param> /// <param name="localizationManager">Instance of the <see cref="ILocalizationManager"/> interface.</param> /// <param name="userViewManager">Instance of the <see cref="IUserViewManager"/> interface.</param> /// <param name="httpClient">Instance of the <see cref="IHttpClient"/> interface.</param> /// <param name="applicationHost">Instance of the <see cref="IApplicationHost"/> interface.</param> public Notifier( ILogger <Notifier> logger, IServerConfigurationManager serverConfiguration, ILibraryManager libraryManager, ILocalizationManager localizationManager, IUserViewManager userViewManager, IHttpClient httpClient, IApplicationHost applicationHost) { _logger = logger; _serverConfiguration = serverConfiguration; _libraryManager = libraryManager; _localizationManager = localizationManager; _userViewManager = userViewManager; _httpClient = httpClient; _applicationHost = applicationHost; _jsonSerializerOptions = JsonDefaults.GetOptions(); _jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; _queuedMessageHandler = new System.Timers.Timer(Constants.MessageQueueSendInterval); _queuedMessageHandler.AutoReset = true; _queuedMessageHandler.Elapsed += QueuedMessageSender; _queuedMessageHandler.Start(); _queuedUpdateHandler = new System.Timers.Timer(Constants.RecheckIntervalMs); _queuedUpdateHandler.AutoReset = true; _queuedUpdateHandler.Elapsed += CheckForMetadata; _queuedUpdateHandler.Start(); _libraryManager.ItemAdded += ItemAddHandler; _logger.LogDebug("Registered ItemAdd handler"); }
public PluginManager( ILogger <PluginManager> logger, IApplicationHost appHost, ServerConfiguration config, string pluginsPath, Version appVersion) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _pluginsPath = pluginsPath; _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); _jsonOptions = new JsonSerializerOptions(JsonDefaults.GetOptions()) { WriteIndented = true }; // We need to use the default GUID converter, so we need to remove any custom ones. for (int a = _jsonOptions.Converters.Count - 1; a >= 0; a--) { if (_jsonOptions.Converters[a] is JsonGuidConverter convertor) { _jsonOptions.Converters.Remove(convertor); break; } } _config = config; _appHost = appHost; _minimumVersion = new Version(0, 0, 0, 1); _plugins = Directory.Exists(_pluginsPath) ? DiscoverPlugins().ToList() : new List <LocalPlugin>(); }
public KodiSyncQueueController(ILogger <KodiSyncQueueController> logger, IUserManager userManager, ILibraryManager libraryManager) { _logger = logger; _userManager = userManager; _libraryManager = libraryManager; _jsonSerializerOptions = JsonDefaults.GetOptions(); }
/// <summary> /// Extension method for adding the jellyfin API to the service collection. /// </summary> /// <param name="serviceCollection">The service collection.</param> /// <param name="pluginAssemblies">An IEnumerable containing all plugin assemblies with API controllers.</param> /// <param name="knownProxies">A list of all known proxies to trust for X-Forwarded-For.</param> /// <returns>The MVC builder.</returns> public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, IEnumerable <Assembly> pluginAssemblies, IReadOnlyList <string> knownProxies) { IMvcBuilder mvcBuilder = serviceCollection .AddCors() .AddTransient <ICorsPolicyProvider, CorsPolicyProvider>() .Configure <ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; for (var i = 0; i < knownProxies.Count; i++) { if (IPAddress.TryParse(knownProxies[i], out var address)) { options.KnownProxies.Add(address); } } }) .AddMvc(opts => { // Allow requester to change between camelCase and PascalCase opts.RespectBrowserAcceptHeader = true; opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter()); opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter()); opts.OutputFormatters.Add(new CssOutputFormatter()); opts.OutputFormatters.Add(new XmlOutputFormatter()); }) // Clear app parts to avoid other assemblies being picked up .ConfigureApplicationPartManager(a => a.ApplicationParts.Clear()) .AddApplicationPart(typeof(StartupController).Assembly) .AddJsonOptions(options => { // Update all properties that are set in JsonDefaults var jsonOptions = JsonDefaults.GetPascalCaseOptions(); // From JsonDefaults options.JsonSerializerOptions.ReadCommentHandling = jsonOptions.ReadCommentHandling; options.JsonSerializerOptions.WriteIndented = jsonOptions.WriteIndented; options.JsonSerializerOptions.DefaultIgnoreCondition = jsonOptions.DefaultIgnoreCondition; options.JsonSerializerOptions.NumberHandling = jsonOptions.NumberHandling; options.JsonSerializerOptions.Converters.Clear(); foreach (var converter in jsonOptions.Converters) { options.JsonSerializerOptions.Converters.Add(converter); } // From JsonDefaults.PascalCase options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy; }); foreach (Assembly pluginAssembly in pluginAssemblies) { mvcBuilder.AddApplicationPart(pluginAssembly); } return(mvcBuilder.AddControllersAsServices()); }
public DbRepo(string dPath, ILogger <DbRepo> logger) { _logger = logger; _logger.LogInformation("Creating DB Repository..."); Directory.CreateDirectory(dPath); _liteDb = new LiteDatabase($"filename={dPath}/kodisyncqueue.db;mode=exclusive"); _jsonSerializerOptions = JsonDefaults.GetOptions(); }
public NotificationController( ILogger <NotificationController> logger, IHttpClientFactory httpClientFactory) { _logger = logger; _httpClientFactory = httpClientFactory; _jsonSerializerOptions = JsonDefaults.GetOptions(); }
public static async Task <T> DeserializeFromHttp <T>(HttpResponseMessage response) { var contentStream = await response.Content.ReadAsStreamAsync(); var result = await JsonSerializer.DeserializeAsync <T>(contentStream, JsonDefaults.GetOptions()); return(result); }
public SqliteDisplayPreferencesRepository(ILogger <SqliteDisplayPreferencesRepository> logger, IApplicationPaths appPaths, IFileSystem fileSystem) : base(logger) { _fileSystem = fileSystem; _jsonOptions = JsonDefaults.GetOptions(); DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db"); }
public SqliteUserRepository( ILogger <SqliteUserRepository> logger, IServerApplicationPaths appPaths) : base(logger) { _jsonOptions = JsonDefaults.GetOptions(); DbFilePath = Path.Combine(appPaths.DataPath, "users.db"); }
public Bf4Client() { _httpClient = new HttpClient() { BaseAddress = new Uri("https://battlelog.battlefield.com") }; _jsonOptions = JsonDefaults.GetOptions(); }
/// <summary> /// Initializes a new instance of the <see cref="PluginsController"/> class. /// </summary> /// <param name="installationManager">Instance of the <see cref="IInstallationManager"/> interface.</param> /// <param name="pluginManager">Instance of the <see cref="IPluginManager"/> interface.</param> /// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param> public PluginsController( IInstallationManager installationManager, IPluginManager pluginManager, IConfigurationManager config) { _installationManager = installationManager; _pluginManager = pluginManager; _serializerOptions = JsonDefaults.GetOptions(); _config = config; }
public async Task Format(Uri url, EventInfo info) { var body = new PlexFormatPayload { @event = GetEventName(info.Event), user = true, owner = info.User.HasPermission(Data.Enums.PermissionKind.IsAdministrator), Account = new { id = info.User.Id, title = info.User.Username }, Server = new { title = info.Server.Name, uuid = info.Server.Id }, Player = new { local = true, publicAddress = info.Session?.RemoteEndPoint, title = info.Session?.DeviceName, uuid = info.Session?.Id, }, Metadata = new { librarySectionType = GetSectionType(info.Item), guid = GetGuid(info.Item), title = info.Item.Name, type = GetMediaType(info.Item), parentTitle = info.Item.DisplayParent.Name, grandparentTitle = info.Item.DisplayParent.DisplayParent.Name, addedAt = ((DateTimeOffset)info.Item.DateCreated).ToUnixTimeSeconds(), updatedAt = ((DateTimeOffset)info.Item.DateModified).ToUnixTimeSeconds(), year = info.Item.ProductionYear, duration = info.Item.RunTimeTicks / 1000, } }; var content = JsonSerializer.Serialize(body, JsonDefaults.GetOptions()); var form = new MultipartFormDataContent { { new StringContent(content), "payload" } }; using (var httpClient = new HttpClient()) { var response = await httpClient.PostAsync(url, form); response.EnsureSuccessStatusCode(); var status = await response.Content.ReadAsStringAsync(); // status from SIMKL can be "OK" or "FAIL" } }
public OmdbProvider(IHttpClientFactory httpClientFactory, IFileSystem fileSystem, IApplicationHost appHost, IServerConfigurationManager configurationManager) { _httpClientFactory = httpClientFactory; _fileSystem = fileSystem; _configurationManager = configurationManager; _appHost = appHost; _jsonOptions = new JsonSerializerOptions(JsonDefaults.GetOptions()); _jsonOptions.Converters.Add(new JsonOmdbNotAvailableStringConverter()); _jsonOptions.Converters.Add(new JsonOmdbNotAvailableInt32Converter()); }
/// <summary> /// Initializes a new instance of the <see cref="NotificationsService"/> class. /// </summary> /// <param name="logger">Instance of the <see cref="ILogger{NoticiationsService}"/> interface.</param> /// <param name="serverConfiguration">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> /// <param name="httpClient">Instance of the <see cref="IHttpClient"/> interface.</param> public NotificationsService( ILogger <NotificationsService> logger, IServerConfigurationManager serverConfiguration, IHttpClient httpClient) { _logger = logger; _serverConfiguration = serverConfiguration; _httpClient = httpClient; _jsonSerializerOptions = JsonDefaults.GetOptions(); _jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }
/// <summary> /// Extension method for adding the jellyfin API to the service collection. /// </summary> /// <param name="serviceCollection">The service collection.</param> /// <param name="baseUrl">The base url for the API.</param> /// <param name="pluginAssemblies">An IEnumberable containing all plugin assemblies with API controllers.</param> /// <returns>The MVC builder.</returns> public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, string baseUrl, IEnumerable <Assembly> pluginAssemblies) { IMvcBuilder mvcBuilder = serviceCollection .AddCors(options => { options.AddPolicy(ServerCorsPolicy.DefaultPolicyName, ServerCorsPolicy.DefaultPolicy); }) .Configure <ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; }) .AddMvc(opts => { opts.UseGeneralRoutePrefix(baseUrl); opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter()); opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter()); opts.OutputFormatters.Add(new CssOutputFormatter()); opts.OutputFormatters.Add(new XmlOutputFormatter()); }) // Clear app parts to avoid other assemblies being picked up .ConfigureApplicationPartManager(a => a.ApplicationParts.Clear()) .AddApplicationPart(typeof(StartupController).Assembly) .AddJsonOptions(options => { // Update all properties that are set in JsonDefaults var jsonOptions = JsonDefaults.GetPascalCaseOptions(); // From JsonDefaults options.JsonSerializerOptions.ReadCommentHandling = jsonOptions.ReadCommentHandling; options.JsonSerializerOptions.WriteIndented = jsonOptions.WriteIndented; options.JsonSerializerOptions.DefaultIgnoreCondition = jsonOptions.DefaultIgnoreCondition; options.JsonSerializerOptions.NumberHandling = jsonOptions.NumberHandling; options.JsonSerializerOptions.Converters.Clear(); foreach (var converter in jsonOptions.Converters) { options.JsonSerializerOptions.Converters.Add(converter); } // From JsonDefaults.PascalCase options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy; }); foreach (Assembly pluginAssembly in pluginAssemblies) { mvcBuilder.AddApplicationPart(pluginAssembly); } return(mvcBuilder.AddControllersAsServices()); }
public WebSocketConnection( ILogger <WebSocketConnection> logger, WebSocket socket, IPAddress?remoteEndPoint, IQueryCollection query) { _logger = logger; _socket = socket; RemoteEndPoint = remoteEndPoint; QueryString = query; _jsonOptions = JsonDefaults.GetOptions(); LastActivityDate = DateTime.Now; }
/// <summary> /// Initializes a new instance of the <see cref="OmdbItemProvider"/> class. /// </summary> /// <param name="httpClientFactory">Instance of the <see cref="IHttpClientFactory"/> interface.</param> /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param> /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param> /// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> public OmdbItemProvider( IHttpClientFactory httpClientFactory, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager configurationManager) { _httpClientFactory = httpClientFactory; _libraryManager = libraryManager; _fileSystem = fileSystem; _configurationManager = configurationManager; _jsonOptions = new JsonSerializerOptions(JsonDefaults.GetOptions()); _jsonOptions.Converters.Add(new JsonOmdbNotAvailableStringConverter()); _jsonOptions.Converters.Add(new JsonOmdbNotAvailableStructConverter <int>()); }
private async Task <BookResult> FetchBookData(string googleBookId, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var url = string.Format(GoogleApiUrls.DetailsUrl, googleBookId); var httpClient = _httpClientFactory.CreateClient(NamedClient.Default); using (var response = await httpClient.GetAsync(url).ConfigureAwait(false)) { await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); return(await JsonSerializer.DeserializeAsync <BookResult>(stream, JsonDefaults.GetOptions()).ConfigureAwait(false)); } }
public async Task Format(Uri url, EventInfo info) { var item = _dto.GetBaseItemDto(info.Item, new DtoOptions(true), info.User); var user = _users.GetUserDto(info.User); var body = new DefaultFormatPayload { Event = info.Event, Item = item, Session = info.Session, User = user, Server = info.Server }; var content = new StringContent(JsonSerializer.Serialize(body, JsonDefaults.GetOptions()), Encoding.UTF8, "application/json"); await _http.PostAsync(url, content); }
public MediaEncoder( ILogger <MediaEncoder> logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILocalizationManager localization, Lazy <EncodingHelper> encodingHelperFactory, IConfiguration config) { _logger = logger; _configurationManager = configurationManager; _fileSystem = fileSystem; _localization = localization; _encodingHelperFactory = encodingHelperFactory; _startupOptionFFmpegPath = config.GetValue <string>(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? string.Empty; _jsonSerializerOptions = JsonDefaults.GetOptions(); }
private async Task <SearchResult> GetSearchResultsInternal(BookInfo item, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // pattern match the filename // year can be included for better results GetBookMetadata(item); var url = string.Format(GoogleApiUrls.SearchUrl, WebUtility.UrlEncode(item.Name), 0, 20); var httpClient = _httpClientFactory.CreateClient(NamedClient.Default); using (var response = await httpClient.GetAsync(url).ConfigureAwait(false)) { await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); return(await JsonSerializer.DeserializeAsync <SearchResult>(stream, JsonDefaults.GetOptions()).ConfigureAwait(false)); } }
public HdHomerunHost( IServerConfigurationManager config, ILogger <HdHomerunHost> logger, IFileSystem fileSystem, IHttpClientFactory httpClientFactory, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, IStreamHelper streamHelper, IMemoryCache memoryCache) : base(config, logger, fileSystem, memoryCache) { _httpClientFactory = httpClientFactory; _appHost = appHost; _socketFactory = socketFactory; _networkManager = networkManager; _streamHelper = streamHelper; _jsonOptions = JsonDefaults.GetOptions(); }
/// <summary> /// Extension method for adding the jellyfin API to the service collection. /// </summary> /// <param name="serviceCollection">The service collection.</param> /// <param name="pluginAssemblies">An IEnumerable containing all plugin assemblies with API controllers.</param> /// <param name="config">The <see cref="NetworkConfiguration"/>.</param> /// <returns>The MVC builder.</returns> public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, IEnumerable <Assembly> pluginAssemblies, NetworkConfiguration config) { IMvcBuilder mvcBuilder = serviceCollection .AddCors() .AddTransient <ICorsPolicyProvider, CorsPolicyProvider>() .Configure <ForwardedHeadersOptions>(options => { // https://github.com/dotnet/aspnetcore/blob/master/src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs // Enable debug logging on Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware to help investigate issues. options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; if (config.KnownProxies.Length == 0) { options.KnownNetworks.Clear(); options.KnownProxies.Clear(); } else { AddProxyAddresses(config, config.KnownProxies, options); } // Only set forward limit if we have some known proxies or some known networks. if (options.KnownProxies.Count != 0 || options.KnownNetworks.Count != 0) { options.ForwardLimit = null; } }) .AddMvc(opts => { // Allow requester to change between camelCase and PascalCase opts.RespectBrowserAcceptHeader = true; opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter()); opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter()); opts.OutputFormatters.Add(new CssOutputFormatter()); opts.OutputFormatters.Add(new XmlOutputFormatter()); opts.ModelBinderProviders.Insert(0, new NullableEnumModelBinderProvider()); }) // Clear app parts to avoid other assemblies being picked up .ConfigureApplicationPartManager(a => a.ApplicationParts.Clear()) .AddApplicationPart(typeof(StartupController).Assembly) .AddJsonOptions(options => { // Update all properties that are set in JsonDefaults var jsonOptions = JsonDefaults.GetPascalCaseOptions(); // From JsonDefaults options.JsonSerializerOptions.ReadCommentHandling = jsonOptions.ReadCommentHandling; options.JsonSerializerOptions.WriteIndented = jsonOptions.WriteIndented; options.JsonSerializerOptions.DefaultIgnoreCondition = jsonOptions.DefaultIgnoreCondition; options.JsonSerializerOptions.NumberHandling = jsonOptions.NumberHandling; options.JsonSerializerOptions.PropertyNameCaseInsensitive = jsonOptions.PropertyNameCaseInsensitive; options.JsonSerializerOptions.Converters.Clear(); foreach (var converter in jsonOptions.Converters) { options.JsonSerializerOptions.Converters.Add(converter); } // From JsonDefaults.PascalCase options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy; }); foreach (Assembly pluginAssembly in pluginAssemblies) { mvcBuilder.AddApplicationPart(pluginAssembly); } return(mvcBuilder.AddControllersAsServices()); }
/// <summary> /// Downloads the series json. /// </summary> /// <param name="tvdbId">The TVDB identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> internal async Task DownloadSeriesJson(string tvdbId, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var url = string.Format( CultureInfo.InvariantCulture, Plugin.BaseUrl, Plugin.ApiKey, tvdbId, "tv"); var clientKey = Plugin.Instance.Configuration.PersonalApiKey; if (!string.IsNullOrWhiteSpace(clientKey)) { url += "&client_key=" + clientKey; } var path = GetJsonPath(tvdbId); Directory.CreateDirectory(Path.GetDirectoryName(path)); try { var httpClient = _httpClientFactory.CreateClient(NamedClient.Default); using (var httpResponse = await httpClient.GetAsync(new Uri(url), cancellationToken).ConfigureAwait(false)) using (var response = httpResponse.Content) using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous)) { await response.CopyToAsync(fileStream, CancellationToken.None).ConfigureAwait(false); } } catch (HttpRequestException exception) { if (exception.StatusCode.HasValue && exception.StatusCode.Value == HttpStatusCode.NotFound) { // If the user has automatic updates enabled, save a dummy object to prevent repeated download attempts Stream fileStream = File.OpenWrite(path); await JsonSerializer.SerializeAsync(fileStream, new RootObject(), JsonDefaults.GetOptions()).ConfigureAwait(false); return; } throw; } }
private async Task AddImages(List <RemoteImageInfo> list, string path) { Stream fileStream = File.OpenRead(path); var root = await JsonSerializer.DeserializeAsync <RootObject>(fileStream, JsonDefaults.GetOptions()).ConfigureAwait(false); AddImages(list, root); }
/// <summary> /// Initializes a new instance of the <see cref="CamelCaseJsonProfileFormatter"/> class. /// </summary> public CamelCaseJsonProfileFormatter() : base(JsonDefaults.GetCamelCaseOptions()) { SupportedMediaTypes.Clear(); SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(JsonDefaults.CamelCaseMediaType)); }
private async Task AddImages(List <RemoteImageInfo> list, int seasonNumber, string path, CancellationToken cancellationToken) { Stream fileStream = File.OpenRead(path); var root = await JsonSerializer.DeserializeAsync <SeriesProvider.RootObject>(fileStream, JsonDefaults.GetOptions()).ConfigureAwait(false); AddImages(list, root, seasonNumber, cancellationToken); }
static void Main(string[] args) { var fileContents = File.ReadAllText(@"D:\workshop\pitstop\pitstop.analyzed.json"); Types = JsonConvert.DeserializeObject <List <TypeDescription> >(fileContents, JsonDefaults.DeserializerSettings()).ToList(); Types.PopulateInheritedBaseTypes(); Types.PopulateInheritedMembers(); var stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# Pitstop Generated Documentation"); stringBuilder.AppendLine(); stringBuilder.AppendLine("## Service Architecture"); stringBuilder.AppendLine(); stringBuilder.AppendLine("![Pitstop solution architecture](https://github.com/EdwinVW/pitstop/wiki/img/solution-architecture.png)"); stringBuilder.AppendLine(); stringBuilder.AppendLine("## Commands"); stringBuilder.AppendLine(); foreach (var group in Types.Where(t => t.ImplementsType("Pitstop.Infrastructure.Messaging.Command")) .GroupBy(t => t.Name) .OrderBy(g => g.Key)) { stringBuilder.AppendLine($"### {group.Key.ToSentenceCase()}"); stringBuilder.AppendLine(); stringBuilder.AppendLine("#### Services"); stringBuilder.AppendLine(); foreach (var command in group.OrderBy(c => c.Namespace)) { stringBuilder.AppendLine($"- {command.Namespace.Split('.').Reverse().Skip(1).First().ToSentenceCase()}"); } stringBuilder.AppendLine(); if (group.SelectMany(t => t.Fields).Any()) { stringBuilder.AppendLine("#### Fields"); stringBuilder.AppendLine(); stringBuilder.AppendLine("|Property|Type|Description|"); stringBuilder.AppendLine("|-|-|-|"); foreach (var field in group.SelectMany(t => t.Fields) .GroupBy(f => (f.Type, f.Name)) .Select(g => g.First()) .OrderBy(f => f.Name)) { stringBuilder.AppendLine($"|{field.Name}|{field.Type.ForDiagram()}|{field.DocumentationComments?.Summary}|"); } stringBuilder.AppendLine(); var type = group.First(); if (Types.CommandHandlerFor(type) != null) { RenderCommandDiagram(stringBuilder, type); } else { stringBuilder.AppendLine("> ❗ No command handler found"); stringBuilder.AppendLine(); } } } stringBuilder.AppendLine("## Events"); stringBuilder.AppendLine(); foreach (var group in Types.Where(t => t.ImplementsType("Pitstop.Infrastructure.Messaging.Event")) .GroupBy(t => t.Name) .OrderBy(t => t.Key)) { stringBuilder.AppendLine($"### {group.Key.ToSentenceCase()}"); stringBuilder.AppendLine(); stringBuilder.AppendLine("#### Services"); stringBuilder.AppendLine(); foreach (var @event in group.OrderBy(e => e.Namespace)) { stringBuilder.AppendLine($"- {@event.Namespace.Split('.').Reverse().Skip(1).First().ToSentenceCase()}"); } stringBuilder.AppendLine(); if (group.SelectMany(t => t.Fields).Any()) { stringBuilder.AppendLine("#### Fields"); stringBuilder.AppendLine(); stringBuilder.AppendLine("|Property|Type|Description|"); stringBuilder.AppendLine("|-|-|-|"); foreach (var field in group.SelectMany(t => t.Fields) .GroupBy(f => (f.Type, f.Name)) .Select(g => g.First()) .OrderBy(f => f.Name)) { stringBuilder.AppendLine($"|{field.Name}|{field.Type.ForDiagram()}|{field.DocumentationComments?.Summary}|"); } stringBuilder.AppendLine(); } } stringBuilder.AppendLine("## Aggregates"); stringBuilder.AppendLine(); foreach (var aggregateRoot in Types.Where(t => t.ImplementsTypeStartsWith("Pitstop.WorkshopManagementAPI.Domain.Core.AggregateRoot<"))) { stringBuilder.AppendLine($"### {aggregateRoot.Name.ToSentenceCase()}"); stringBuilder.AppendLine(); var aggregateIDType = Types.First(aggregateRoot.BaseTypes.First(bt => bt.StartsWith("Pitstop.WorkshopManagementAPI.Domain.Core.AggregateRoot<")).GenericTypes().First()); stringBuilder.AppendLine("```plantuml"); stringBuilder.UmlDiagramStart(); RenderClass(stringBuilder, aggregateIDType); stringBuilder.AppendLine($"{aggregateIDType.Name} -- {aggregateRoot.Name}"); RenderClass(stringBuilder, aggregateRoot); stringBuilder.UmlDiagramEnd(); stringBuilder.AppendLine("```"); stringBuilder.AppendLine(); } File.WriteAllText("pitstop.generated.md", stringBuilder.ToString()); }
/// <inheritdoc/> public void Perform() { var dataPath = _paths.DataPath; _logger.LogInformation("Migrating the user database may take a while, do not stop Jellyfin."); using (var connection = SQLite3.Open(Path.Combine(dataPath, DbFilename), ConnectionFlags.ReadOnly, null)) { var dbContext = _provider.CreateContext(); var queryResult = connection.Query("SELECT * FROM LocalUsersv2"); dbContext.RemoveRange(dbContext.Users); dbContext.SaveChanges(); foreach (var entry in queryResult) { UserMockup?mockup = JsonSerializer.Deserialize <UserMockup>(entry[2].ToBlob(), JsonDefaults.GetOptions()); if (mockup == null) { continue; } var userDataDir = Path.Combine(_paths.UserConfigurationDirectoryPath, mockup.Name); var config = File.Exists(Path.Combine(userDataDir, "config.xml")) ? (UserConfiguration)_xmlSerializer.DeserializeFromFile(typeof(UserConfiguration), Path.Combine(userDataDir, "config.xml")) : new UserConfiguration(); var policy = File.Exists(Path.Combine(userDataDir, "policy.xml")) ? (UserPolicy)_xmlSerializer.DeserializeFromFile(typeof(UserPolicy), Path.Combine(userDataDir, "policy.xml")) : new UserPolicy(); policy.AuthenticationProviderId = policy.AuthenticationProviderId?.Replace( "Emby.Server.Implementations.Library", "Jellyfin.Server.Implementations.Users", StringComparison.Ordinal) ?? typeof(DefaultAuthenticationProvider).FullName; policy.PasswordResetProviderId = typeof(DefaultPasswordResetProvider).FullName; int?maxLoginAttempts = policy.LoginAttemptsBeforeLockout switch { -1 => null, 0 => 3, _ => policy.LoginAttemptsBeforeLockout }; var user = new User(mockup.Name, policy.AuthenticationProviderId, policy.PasswordResetProviderId) { Id = entry[1].ReadGuidFromBlob(), InternalId = entry[0].ToInt64(), MaxParentalAgeRating = policy.MaxParentalRating, EnableUserPreferenceAccess = policy.EnableUserPreferenceAccess, RemoteClientBitrateLimit = policy.RemoteClientBitrateLimit, InvalidLoginAttemptCount = policy.InvalidLoginAttemptCount, LoginAttemptsBeforeLockout = maxLoginAttempts, SubtitleMode = config.SubtitleMode, HidePlayedInLatest = config.HidePlayedInLatest, EnableLocalPassword = config.EnableLocalPassword, PlayDefaultAudioTrack = config.PlayDefaultAudioTrack, DisplayCollectionsView = config.DisplayCollectionsView, DisplayMissingEpisodes = config.DisplayMissingEpisodes, AudioLanguagePreference = config.AudioLanguagePreference, RememberAudioSelections = config.RememberAudioSelections, EnableNextEpisodeAutoPlay = config.EnableNextEpisodeAutoPlay, RememberSubtitleSelections = config.RememberSubtitleSelections, SubtitleLanguagePreference = config.SubtitleLanguagePreference, Password = mockup.Password, EasyPassword = mockup.EasyPassword, LastLoginDate = mockup.LastLoginDate, LastActivityDate = mockup.LastActivityDate }; if (mockup.ImageInfos.Length > 0) { ItemImageInfo info = mockup.ImageInfos[0]; user.ProfileImage = new ImageInfo(info.Path) { LastModified = info.DateModified }; } user.SetPermission(PermissionKind.IsAdministrator, policy.IsAdministrator); user.SetPermission(PermissionKind.IsHidden, policy.IsHidden); user.SetPermission(PermissionKind.IsDisabled, policy.IsDisabled); user.SetPermission(PermissionKind.EnableSharedDeviceControl, policy.EnableSharedDeviceControl); user.SetPermission(PermissionKind.EnableRemoteAccess, policy.EnableRemoteAccess); user.SetPermission(PermissionKind.EnableLiveTvManagement, policy.EnableLiveTvManagement); user.SetPermission(PermissionKind.EnableLiveTvAccess, policy.EnableLiveTvAccess); user.SetPermission(PermissionKind.EnableMediaPlayback, policy.EnableMediaPlayback); user.SetPermission(PermissionKind.EnableAudioPlaybackTranscoding, policy.EnableAudioPlaybackTranscoding); user.SetPermission(PermissionKind.EnableVideoPlaybackTranscoding, policy.EnableVideoPlaybackTranscoding); user.SetPermission(PermissionKind.EnableContentDeletion, policy.EnableContentDeletion); user.SetPermission(PermissionKind.EnableContentDownloading, policy.EnableContentDownloading); user.SetPermission(PermissionKind.EnableSyncTranscoding, policy.EnableSyncTranscoding); user.SetPermission(PermissionKind.EnableMediaConversion, policy.EnableMediaConversion); user.SetPermission(PermissionKind.EnableAllChannels, policy.EnableAllChannels); user.SetPermission(PermissionKind.EnableAllDevices, policy.EnableAllDevices); user.SetPermission(PermissionKind.EnableAllFolders, policy.EnableAllFolders); user.SetPermission(PermissionKind.EnableRemoteControlOfOtherUsers, policy.EnableRemoteControlOfOtherUsers); user.SetPermission(PermissionKind.EnablePlaybackRemuxing, policy.EnablePlaybackRemuxing); user.SetPermission(PermissionKind.ForceRemoteSourceTranscoding, policy.ForceRemoteSourceTranscoding); user.SetPermission(PermissionKind.EnablePublicSharing, policy.EnablePublicSharing); foreach (var policyAccessSchedule in policy.AccessSchedules) { user.AccessSchedules.Add(policyAccessSchedule); } user.SetPreference(PreferenceKind.BlockedTags, policy.BlockedTags); user.SetPreference(PreferenceKind.EnabledChannels, policy.EnabledChannels?.Select(i => i.ToString("N", CultureInfo.InvariantCulture)).ToArray()); user.SetPreference(PreferenceKind.EnabledDevices, policy.EnabledDevices); user.SetPreference(PreferenceKind.EnabledFolders, policy.EnabledFolders?.Select(i => i.ToString("N", CultureInfo.InvariantCulture)).ToArray()); user.SetPreference(PreferenceKind.EnableContentDeletionFromFolders, policy.EnableContentDeletionFromFolders); user.SetPreference(PreferenceKind.OrderedViews, config.OrderedViews); user.SetPreference(PreferenceKind.GroupedFolders, config.GroupedFolders); user.SetPreference(PreferenceKind.MyMediaExcludes, config.MyMediaExcludes); user.SetPreference(PreferenceKind.LatestItemExcludes, config.LatestItemsExcludes); dbContext.Users.Add(user); } dbContext.SaveChanges(); } try { File.Move(Path.Combine(dataPath, DbFilename), Path.Combine(dataPath, DbFilename + ".old")); var journalPath = Path.Combine(dataPath, DbFilename + "-journal"); if (File.Exists(journalPath)) { File.Move(journalPath, Path.Combine(dataPath, DbFilename + ".old-journal")); } } catch (IOException e) { _logger.LogError(e, "Error renaming legacy user database to 'users.db.old'"); } } #nullable disable