|
@ -1 +1,5 @@
|
||||||
.git
|
.git
|
||||||
|
.dockerignore
|
||||||
|
Dockerfile
|
||||||
|
CONTRIBUTORS.md
|
||||||
|
README.md
|
||||||
|
|
28
.drone.yml
|
@ -1,32 +1,12 @@
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: build:debian
|
name: build
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: submodules
|
- name: submodules
|
||||||
image: docker:git
|
image: docker:git
|
||||||
commands:
|
commands:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
- name: build:debian
|
- name: build
|
||||||
image: plugins/docker
|
image: microsoft/dotnet:2-sdk
|
||||||
group: build
|
|
||||||
settings:
|
|
||||||
repo: jellyfin/jellyfin
|
|
||||||
dry_run: true
|
|
||||||
dockerfile: Dockerfile.debian_package
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: build:docker
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: submodules
|
|
||||||
image: docker:git
|
|
||||||
commands:
|
commands:
|
||||||
- git submodule update --init --recursive
|
- dotnet publish --configuration release --output /release
|
||||||
- name: build:docker
|
|
||||||
image: plugins/docker
|
|
||||||
group: build
|
|
||||||
settings:
|
|
||||||
repo: jellyfin/jellyfin
|
|
||||||
dry_run: true
|
|
||||||
|
|
133
.editorconfig
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
# With more recent updates Visual Studio 2017 supports EditorConfig files out of the box
|
||||||
|
# Visual Studio Code needs an extension: https://github.com/editorconfig/editorconfig-vscode
|
||||||
|
# For emacs, vim, np++ and other editors, see here: https://github.com/editorconfig
|
||||||
|
###############################
|
||||||
|
# Core EditorConfig Options #
|
||||||
|
###############################
|
||||||
|
# All files
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
root = true
|
||||||
|
indent_size = 4
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
end_of_line = lf
|
||||||
|
max_line_length = null
|
||||||
|
|
||||||
|
# Code files
|
||||||
|
[*.{cs,csx,vb,vbx}]
|
||||||
|
indent_size = 4
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
###############################
|
||||||
|
# .NET Coding Conventions #
|
||||||
|
###############################
|
||||||
|
[*.{cs,vb}]
|
||||||
|
# Organize usings
|
||||||
|
dotnet_sort_system_directives_first = true
|
||||||
|
# this. preferences
|
||||||
|
dotnet_style_qualification_for_field = false:silent
|
||||||
|
dotnet_style_qualification_for_property = false:silent
|
||||||
|
dotnet_style_qualification_for_method = false:silent
|
||||||
|
dotnet_style_qualification_for_event = false:silent
|
||||||
|
# Language keywords vs BCL types preferences
|
||||||
|
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||||
|
dotnet_style_predefined_type_for_member_access = true:silent
|
||||||
|
# Parentheses preferences
|
||||||
|
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
|
||||||
|
# Modifier preferences
|
||||||
|
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||||
|
dotnet_style_readonly_field = true:suggestion
|
||||||
|
# Expression-level preferences
|
||||||
|
dotnet_style_object_initializer = true:suggestion
|
||||||
|
dotnet_style_collection_initializer = true:suggestion
|
||||||
|
dotnet_style_explicit_tuple_names = true:suggestion
|
||||||
|
dotnet_style_null_propagation = true:suggestion
|
||||||
|
dotnet_style_coalesce_expression = true:suggestion
|
||||||
|
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
|
||||||
|
dotnet_prefer_inferred_tuple_names = true:suggestion
|
||||||
|
dotnet_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||||
|
dotnet_style_prefer_auto_properties = true:silent
|
||||||
|
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||||
|
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||||
|
###############################
|
||||||
|
# Naming Conventions #
|
||||||
|
###############################
|
||||||
|
# Style Definitions
|
||||||
|
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
|
||||||
|
# Use PascalCase for constant fields
|
||||||
|
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
|
||||||
|
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
|
||||||
|
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
|
||||||
|
dotnet_naming_symbols.constant_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
|
||||||
|
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
||||||
|
###############################
|
||||||
|
# C# Coding Conventions #
|
||||||
|
###############################
|
||||||
|
[*.cs]
|
||||||
|
# var preferences
|
||||||
|
csharp_style_var_for_built_in_types = true:silent
|
||||||
|
csharp_style_var_when_type_is_apparent = true:silent
|
||||||
|
csharp_style_var_elsewhere = true:silent
|
||||||
|
# Expression-bodied members
|
||||||
|
csharp_style_expression_bodied_methods = false:silent
|
||||||
|
csharp_style_expression_bodied_constructors = false:silent
|
||||||
|
csharp_style_expression_bodied_operators = false:silent
|
||||||
|
csharp_style_expression_bodied_properties = true:silent
|
||||||
|
csharp_style_expression_bodied_indexers = true:silent
|
||||||
|
csharp_style_expression_bodied_accessors = true:silent
|
||||||
|
# Pattern matching preferences
|
||||||
|
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||||
|
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||||
|
# Null-checking preferences
|
||||||
|
csharp_style_throw_expression = true:suggestion
|
||||||
|
csharp_style_conditional_delegate_call = true:suggestion
|
||||||
|
# Modifier preferences
|
||||||
|
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
||||||
|
# Expression-level preferences
|
||||||
|
csharp_prefer_braces = true:silent
|
||||||
|
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||||
|
csharp_prefer_simple_default_expression = true:suggestion
|
||||||
|
csharp_style_pattern_local_over_anonymous_function = true:suggestion
|
||||||
|
csharp_style_inlined_variable_declaration = true:suggestion
|
||||||
|
###############################
|
||||||
|
# C# Formatting Rules #
|
||||||
|
###############################
|
||||||
|
# New line preferences
|
||||||
|
csharp_new_line_before_open_brace = all
|
||||||
|
csharp_new_line_before_else = true
|
||||||
|
csharp_new_line_before_catch = true
|
||||||
|
csharp_new_line_before_finally = true
|
||||||
|
csharp_new_line_before_members_in_object_initializers = true
|
||||||
|
csharp_new_line_before_members_in_anonymous_types = true
|
||||||
|
csharp_new_line_between_query_expression_clauses = true
|
||||||
|
# Indentation preferences
|
||||||
|
csharp_indent_case_contents = true
|
||||||
|
csharp_indent_switch_labels = true
|
||||||
|
csharp_indent_labels = flush_left
|
||||||
|
# Space preferences
|
||||||
|
csharp_space_after_cast = false
|
||||||
|
csharp_space_after_keywords_in_control_flow_statements = true
|
||||||
|
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_parentheses = false
|
||||||
|
csharp_space_before_colon_in_inheritance_clause = true
|
||||||
|
csharp_space_after_colon_in_inheritance_clause = true
|
||||||
|
csharp_space_around_binary_operators = before_and_after
|
||||||
|
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||||
|
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||||
|
# Wrapping preferences
|
||||||
|
csharp_preserve_single_line_statements = true
|
||||||
|
csharp_preserve_single_line_blocks = true
|
||||||
|
###############################
|
||||||
|
# VB Coding Conventions #
|
||||||
|
###############################
|
||||||
|
[*.vb]
|
||||||
|
# Modifier preferences
|
||||||
|
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
|
4
.gitignore
vendored
|
@ -1,5 +1,7 @@
|
||||||
!*
|
!*
|
||||||
|
|
||||||
|
.directory
|
||||||
|
|
||||||
#################
|
#################
|
||||||
## Eclipse
|
## Eclipse
|
||||||
#################
|
#################
|
||||||
|
@ -245,6 +247,8 @@ MediaBrowser.WebDashboard/dashboard-ui/.idea/
|
||||||
#########################
|
#########################
|
||||||
|
|
||||||
debian/.debhelper/
|
debian/.debhelper/
|
||||||
|
debian/*.debhelper
|
||||||
|
debian/debhelper-build-stamp
|
||||||
debian/files
|
debian/files
|
||||||
debian/jellyfin.substvars
|
debian/jellyfin.substvars
|
||||||
debian/jellyfin/
|
debian/jellyfin/
|
||||||
|
|
28
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||||
|
// Use hover for the description of the existing attributes
|
||||||
|
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": ".NET Core Launch (console)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
// If you have changed target frameworks, make sure to update the program path.
|
||||||
|
"program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/netcoreapp2.1/jellyfin.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}/Jellyfin.Server",
|
||||||
|
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
|
||||||
|
"console": "internalConsole",
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"internalConsoleOptions": "openOnSessionStart"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Attach",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach",
|
||||||
|
"processId": "${command:pickProcess}"
|
||||||
|
}
|
||||||
|
,]
|
||||||
|
}
|
15
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/Jellyfin.Server/Jellyfin.Server.csproj"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -7,6 +7,10 @@
|
||||||
- [EraYaN](https://github.com/EraYaN)
|
- [EraYaN](https://github.com/EraYaN)
|
||||||
- [flemse](https://github.com/flemse)
|
- [flemse](https://github.com/flemse)
|
||||||
- [bfayers](https://github.com/bfayers)
|
- [bfayers](https://github.com/bfayers)
|
||||||
|
- [Bond_009](https://github.com/Bond-009)
|
||||||
|
- [AnthonyLavado](https://github.com/anthonylavado)
|
||||||
|
- [sparky8251](https://github.com/sparky8251)
|
||||||
|
- [LeoVerto](https://github.com/LeoVerto]
|
||||||
|
|
||||||
# Emby Contributors
|
# Emby Contributors
|
||||||
|
|
||||||
|
|
20
Dockerfile
|
@ -1,5 +1,15 @@
|
||||||
ARG DOTNET_VERSION=2
|
ARG DOTNET_VERSION=2
|
||||||
|
|
||||||
|
|
||||||
|
# Download ffmpeg first to allow quicker rebuild of other layers
|
||||||
|
FROM alpine as ffmpeg
|
||||||
|
ARG FFMPEG_URL=https://www.johnvansickle.com/ffmpeg/old-releases/ffmpeg-4.0.3-64bit-static.tar.xz
|
||||||
|
RUN wget ${FFMPEG_URL} -O - | tar Jxf - \
|
||||||
|
&& mkdir ffmpeg-bin \
|
||||||
|
&& mv ffmpeg*/ffmpeg ffmpeg-bin \
|
||||||
|
&& mv ffmpeg*/ffprobe ffmpeg-bin
|
||||||
|
|
||||||
|
|
||||||
FROM microsoft/dotnet:${DOTNET_VERSION}-sdk as builder
|
FROM microsoft/dotnet:${DOTNET_VERSION}-sdk as builder
|
||||||
WORKDIR /repo
|
WORKDIR /repo
|
||||||
COPY . .
|
COPY . .
|
||||||
|
@ -7,12 +17,12 @@ RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \
|
||||||
&& dotnet clean \
|
&& dotnet clean \
|
||||||
&& dotnet publish --configuration release --output /jellyfin
|
&& dotnet publish --configuration release --output /jellyfin
|
||||||
|
|
||||||
|
|
||||||
FROM microsoft/dotnet:${DOTNET_VERSION}-runtime
|
FROM microsoft/dotnet:${DOTNET_VERSION}-runtime
|
||||||
COPY --from=builder /jellyfin /jellyfin
|
COPY --from=builder /jellyfin /jellyfin
|
||||||
|
COPY --from=ffmpeg /ffmpeg-bin/* /usr/bin/
|
||||||
EXPOSE 8096
|
EXPOSE 8096
|
||||||
RUN apt update \
|
|
||||||
&& apt install -y ffmpeg
|
|
||||||
VOLUME /config /media
|
VOLUME /config /media
|
||||||
ENTRYPOINT if [ -n "$PUID$PGUID" ]; \
|
RUN apt update \
|
||||||
then echo "PUID/PGID are deprecated. Use Docker user param." >&2; exit 1; \
|
&& apt install -y libfontconfig1 # needed for Skia
|
||||||
else dotnet /jellyfin/jellyfin.dll -programdata /config; fi
|
ENTRYPOINT dotnet /jellyfin/jellyfin.dll -programdata /config
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using Emby.Dlna.Service;
|
using Emby.Dlna.Service;
|
||||||
using MediaBrowser.Model.Logging;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MediaBrowser.Model.Xml;
|
using MediaBrowser.Model.Xml;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Dlna.ConnectionManager
|
namespace Emby.Dlna.ConnectionManager
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@ using MediaBrowser.Controller.Configuration;
|
||||||
using Emby.Dlna.Server;
|
using Emby.Dlna.Server;
|
||||||
using Emby.Dlna.Service;
|
using Emby.Dlna.Service;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MediaBrowser.Model.Xml;
|
using MediaBrowser.Model.Xml;
|
||||||
|
|
|
@ -6,7 +6,7 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using Emby.Dlna.Service;
|
using Emby.Dlna.Service;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
|
|
|
@ -12,7 +12,7 @@ using Emby.Dlna.Service;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -68,7 +68,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
_profile = profile;
|
_profile = profile;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
_didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, Logger, libraryManager, mediaEncoder);
|
_didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, _logger, libraryManager, mediaEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, IDictionary<string, string> methodParams)
|
protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, IDictionary<string, string> methodParams)
|
||||||
|
@ -1334,7 +1334,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Error("Error parsing item Id: {0}. Returning user root folder.", id);
|
_logger.LogError("Error parsing item Id: {id}. Returning user root folder.", id);
|
||||||
|
|
||||||
return new ServerItem(_libraryManager.GetUserRootFolder());
|
return new ServerItem(_libraryManager.GetUserRootFolder());
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ using Emby.Dlna.ContentDirectory;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -173,16 +173,6 @@ namespace Emby.Dlna.Didl
|
||||||
writer.WriteFullEndElement();
|
writer.WriteFullEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ILogger GetStreamBuilderLogger(DlnaOptions options)
|
|
||||||
{
|
|
||||||
if (options.EnableDebugLog)
|
|
||||||
{
|
|
||||||
return _logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NullLogger();
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetMimeType(string input)
|
private string GetMimeType(string input)
|
||||||
{
|
{
|
||||||
var mime = MimeTypes.GetMimeType(input);
|
var mime = MimeTypes.GetMimeType(input);
|
||||||
|
@ -202,7 +192,7 @@ namespace Emby.Dlna.Didl
|
||||||
{
|
{
|
||||||
var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user);
|
var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user);
|
||||||
|
|
||||||
streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions
|
streamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildVideoItem(new VideoOptions
|
||||||
{
|
{
|
||||||
ItemId = video.Id,
|
ItemId = video.Id,
|
||||||
MediaSources = sources.ToArray(),
|
MediaSources = sources.ToArray(),
|
||||||
|
@ -509,7 +499,7 @@ namespace Emby.Dlna.Didl
|
||||||
{
|
{
|
||||||
var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user);
|
var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user);
|
||||||
|
|
||||||
streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions
|
streamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildAudioItem(new AudioOptions
|
||||||
{
|
{
|
||||||
ItemId = audio.Id,
|
ItemId = audio.Id,
|
||||||
MediaSources = sources.ToArray(),
|
MediaSources = sources.ToArray(),
|
||||||
|
@ -923,9 +913,9 @@ namespace Emby.Dlna.Didl
|
||||||
|
|
||||||
writer.WriteFullEndElement();
|
writer.WriteFullEndElement();
|
||||||
}
|
}
|
||||||
catch (XmlException)
|
catch (XmlException ex)
|
||||||
{
|
{
|
||||||
//_logger.Error("Error adding xml value: " + value);
|
_logger.LogError(ex, "Error adding xml value: {value}", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,9 +925,9 @@ namespace Emby.Dlna.Didl
|
||||||
{
|
{
|
||||||
writer.WriteElementString(prefix, name, namespaceUri, value);
|
writer.WriteElementString(prefix, name, namespaceUri, value);
|
||||||
}
|
}
|
||||||
catch (XmlException)
|
catch (XmlException ex)
|
||||||
{
|
{
|
||||||
//_logger.Error("Error adding xml value: " + value);
|
_logger.LogError(ex, "Error adding xml value: {value}", value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1080,9 +1070,9 @@ namespace Emby.Dlna.Didl
|
||||||
{
|
{
|
||||||
tag = _imageProcessor.GetImageCacheTag(item, type);
|
tag = _imageProcessor.GetImageCacheTag(item, type);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_logger.LogError(ex, "Error getting image cache tag");
|
||||||
}
|
}
|
||||||
|
|
||||||
int? width = imageInfo.Width;
|
int? width = imageInfo.Width;
|
||||||
|
|
|
@ -8,7 +8,7 @@ using Emby.Dlna.Profiles;
|
||||||
using Emby.Dlna.Server;
|
using Emby.Dlna.Server;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -58,7 +58,7 @@ namespace Emby.Dlna
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error extracting DLNA profiles.", ex);
|
_logger.LogError(ex, "Error extracting DLNA profiles.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ namespace Emby.Dlna
|
||||||
|
|
||||||
if (profile != null)
|
if (profile != null)
|
||||||
{
|
{
|
||||||
_logger.Debug("Found matching device profile: {0}", profile.Name);
|
_logger.LogDebug("Found matching device profile: {0}", profile.Name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -117,6 +117,7 @@ namespace Emby.Dlna
|
||||||
{
|
{
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
|
builder.AppendLine("No matching device profile found. The default will need to be used.");
|
||||||
builder.AppendLine(string.Format("DeviceDescription:{0}", profile.DeviceDescription ?? string.Empty));
|
builder.AppendLine(string.Format("DeviceDescription:{0}", profile.DeviceDescription ?? string.Empty));
|
||||||
builder.AppendLine(string.Format("FriendlyName:{0}", profile.FriendlyName ?? string.Empty));
|
builder.AppendLine(string.Format("FriendlyName:{0}", profile.FriendlyName ?? string.Empty));
|
||||||
builder.AppendLine(string.Format("Manufacturer:{0}", profile.Manufacturer ?? string.Empty));
|
builder.AppendLine(string.Format("Manufacturer:{0}", profile.Manufacturer ?? string.Empty));
|
||||||
|
@ -127,7 +128,7 @@ namespace Emby.Dlna
|
||||||
builder.AppendLine(string.Format("ModelUrl:{0}", profile.ModelUrl ?? string.Empty));
|
builder.AppendLine(string.Format("ModelUrl:{0}", profile.ModelUrl ?? string.Empty));
|
||||||
builder.AppendLine(string.Format("SerialNumber:{0}", profile.SerialNumber ?? string.Empty));
|
builder.AppendLine(string.Format("SerialNumber:{0}", profile.SerialNumber ?? string.Empty));
|
||||||
|
|
||||||
_logger.LogMultiline("No matching device profile found. The default will need to be used.", LogSeverity.Info, builder);
|
_logger.LogInformation(builder.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsMatch(DeviceIdentification deviceInfo, DeviceIdentification profileInfo)
|
private bool IsMatch(DeviceIdentification deviceInfo, DeviceIdentification profileInfo)
|
||||||
|
@ -197,7 +198,7 @@ namespace Emby.Dlna
|
||||||
}
|
}
|
||||||
catch (ArgumentException ex)
|
catch (ArgumentException ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error evaluating regex pattern {0}", ex, pattern);
|
_logger.LogError(ex, "Error evaluating regex pattern {Pattern}", pattern);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,12 +217,12 @@ namespace Emby.Dlna
|
||||||
|
|
||||||
if (profile != null)
|
if (profile != null)
|
||||||
{
|
{
|
||||||
_logger.Debug("Found matching device profile: {0}", profile.Name);
|
_logger.LogDebug("Found matching device profile: {0}", profile.Name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var headerString = string.Join(", ", headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
|
var headerString = string.Join(", ", headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
|
||||||
_logger.Debug("No matching device profile found. {0}", headerString);
|
_logger.LogDebug("No matching device profile found. {0}", headerString);
|
||||||
}
|
}
|
||||||
|
|
||||||
return profile;
|
return profile;
|
||||||
|
@ -250,7 +251,7 @@ namespace Emby.Dlna
|
||||||
return string.Equals(value, header.Value, StringComparison.OrdinalIgnoreCase);
|
return string.Equals(value, header.Value, StringComparison.OrdinalIgnoreCase);
|
||||||
case HeaderMatchType.Substring:
|
case HeaderMatchType.Substring:
|
||||||
var isMatch = value.IndexOf(header.Value, StringComparison.OrdinalIgnoreCase) != -1;
|
var isMatch = value.IndexOf(header.Value, StringComparison.OrdinalIgnoreCase) != -1;
|
||||||
//_logger.Debug("IsMatch-Substring value: {0} testValue: {1} isMatch: {2}", value, header.Value, isMatch);
|
//_logger.LogDebug("IsMatch-Substring value: {0} testValue: {1} isMatch: {2}", value, header.Value, isMatch);
|
||||||
return isMatch;
|
return isMatch;
|
||||||
case HeaderMatchType.Regex:
|
case HeaderMatchType.Regex:
|
||||||
return Regex.IsMatch(value, header.Value, RegexOptions.IgnoreCase);
|
return Regex.IsMatch(value, header.Value, RegexOptions.IgnoreCase);
|
||||||
|
@ -323,7 +324,7 @@ namespace Emby.Dlna
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error parsing profile file: {0}", ex, path);
|
_logger.LogError(ex, "Error parsing profile file: {Path}", path);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -530,8 +531,8 @@ namespace Emby.Dlna
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
class DlnaProfileEntryPoint /*: IServerEntryPoint*/
|
class DlnaProfileEntryPoint : IServerEntryPoint
|
||||||
{
|
{
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
@ -551,7 +552,7 @@ namespace Emby.Dlna
|
||||||
|
|
||||||
private void DumpProfiles()
|
private void DumpProfiles()
|
||||||
{
|
{
|
||||||
var list = new List<DeviceProfile>
|
DeviceProfile[] list = new []
|
||||||
{
|
{
|
||||||
new SamsungSmartTvProfile(),
|
new SamsungSmartTvProfile(),
|
||||||
new XboxOneProfile(),
|
new XboxOneProfile(),
|
||||||
|
@ -596,5 +597,5 @@ namespace Emby.Dlna
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -34,7 +34,7 @@ namespace Emby.Dlna.Eventing
|
||||||
|
|
||||||
// Remove logging for now because some devices are sending this very frequently
|
// Remove logging for now because some devices are sending this very frequently
|
||||||
// TODO re-enable with dlna debug logging setting
|
// TODO re-enable with dlna debug logging setting
|
||||||
//_logger.Debug("Renewing event subscription for {0} with timeout of {1} to {2}",
|
//_logger.LogDebug("Renewing event subscription for {0} with timeout of {1} to {2}",
|
||||||
// subscription.NotificationType,
|
// subscription.NotificationType,
|
||||||
// timeout,
|
// timeout,
|
||||||
// subscription.CallbackUrl);
|
// subscription.CallbackUrl);
|
||||||
|
@ -60,7 +60,7 @@ namespace Emby.Dlna.Eventing
|
||||||
|
|
||||||
// Remove logging for now because some devices are sending this very frequently
|
// Remove logging for now because some devices are sending this very frequently
|
||||||
// TODO re-enable with dlna debug logging setting
|
// TODO re-enable with dlna debug logging setting
|
||||||
//_logger.Debug("Creating event subscription for {0} with timeout of {1} to {2}",
|
//_logger.LogDebug("Creating event subscription for {0} with timeout of {1} to {2}",
|
||||||
// notificationType,
|
// notificationType,
|
||||||
// timeout,
|
// timeout,
|
||||||
// callbackUrl);
|
// callbackUrl);
|
||||||
|
@ -96,7 +96,7 @@ namespace Emby.Dlna.Eventing
|
||||||
|
|
||||||
public EventSubscriptionResponse CancelEventSubscription(string subscriptionId)
|
public EventSubscriptionResponse CancelEventSubscription(string subscriptionId)
|
||||||
{
|
{
|
||||||
_logger.Debug("Cancelling event subscription {0}", subscriptionId);
|
_logger.LogDebug("Cancelling event subscription {0}", subscriptionId);
|
||||||
|
|
||||||
EventSubscription sub;
|
EventSubscription sub;
|
||||||
_subscriptions.TryRemove(subscriptionId, out sub);
|
_subscriptions.TryRemove(subscriptionId, out sub);
|
||||||
|
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 932 B After Width: | Height: | Size: 2.5 KiB |
|
@ -11,7 +11,7 @@ using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Controller.TV;
|
using MediaBrowser.Controller.TV;
|
||||||
using Emby.Dlna.PlayTo;
|
using Emby.Dlna.PlayTo;
|
||||||
using Emby.Dlna.Ssdp;
|
using Emby.Dlna.Ssdp;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -64,7 +64,7 @@ namespace Emby.Dlna.Main
|
||||||
public static DlnaEntryPoint Current;
|
public static DlnaEntryPoint Current;
|
||||||
|
|
||||||
public DlnaEntryPoint(IServerConfigurationManager config,
|
public DlnaEntryPoint(IServerConfigurationManager config,
|
||||||
ILogManager logManager,
|
ILoggerFactory loggerFactory,
|
||||||
IServerApplicationHost appHost,
|
IServerApplicationHost appHost,
|
||||||
ISessionManager sessionManager,
|
ISessionManager sessionManager,
|
||||||
IHttpClient httpClient,
|
IHttpClient httpClient,
|
||||||
|
@ -102,7 +102,7 @@ namespace Emby.Dlna.Main
|
||||||
_timerFactory = timerFactory;
|
_timerFactory = timerFactory;
|
||||||
_environmentInfo = environmentInfo;
|
_environmentInfo = environmentInfo;
|
||||||
_networkManager = networkManager;
|
_networkManager = networkManager;
|
||||||
_logger = logManager.GetLogger("Dlna");
|
_logger = loggerFactory.CreateLogger("Dlna");
|
||||||
|
|
||||||
ContentDirectory = new ContentDirectory.ContentDirectory(dlnaManager,
|
ContentDirectory = new ContentDirectory.ContentDirectory(dlnaManager,
|
||||||
userDataManager,
|
userDataManager,
|
||||||
|
@ -185,13 +185,13 @@ namespace Emby.Dlna.Main
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error starting ssdp handlers", ex);
|
_logger.LogError(ex, "Error starting ssdp handlers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LogMessage(string msg)
|
private void LogMessage(string msg)
|
||||||
{
|
{
|
||||||
_logger.Debug(msg);
|
_logger.LogDebug(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartDeviceDiscovery(ISsdpCommunicationsServer communicationsServer)
|
private void StartDeviceDiscovery(ISsdpCommunicationsServer communicationsServer)
|
||||||
|
@ -202,7 +202,7 @@ namespace Emby.Dlna.Main
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error starting device discovery", ex);
|
_logger.LogError(ex, "Error starting device discovery");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,12 +210,12 @@ namespace Emby.Dlna.Main
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.Info("Disposing DeviceDiscovery");
|
_logger.LogInformation("Disposing DeviceDiscovery");
|
||||||
((DeviceDiscovery)_deviceDiscovery).Dispose();
|
((DeviceDiscovery)_deviceDiscovery).Dispose();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error stopping device discovery", ex);
|
_logger.LogError(ex, "Error stopping device discovery");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ namespace Emby.Dlna.Main
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error registering endpoint", ex);
|
_logger.LogError(ex, "Error registering endpoint");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ namespace Emby.Dlna.Main
|
||||||
|
|
||||||
var fullService = "urn:schemas-upnp-org:device:MediaServer:1";
|
var fullService = "urn:schemas-upnp-org:device:MediaServer:1";
|
||||||
|
|
||||||
_logger.Info("Registering publisher for {0} on {1}", fullService, address.ToString());
|
_logger.LogInformation("Registering publisher for {0} on {1}", fullService, address.ToString());
|
||||||
|
|
||||||
var descriptorUri = "/dlna/" + udn + "/description.xml";
|
var descriptorUri = "/dlna/" + udn + "/description.xml";
|
||||||
var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorUri);
|
var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorUri);
|
||||||
|
@ -361,7 +361,7 @@ namespace Emby.Dlna.Main
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error starting PlayTo manager", ex);
|
_logger.LogError(ex, "Error starting PlayTo manager");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,12 +374,12 @@ namespace Emby.Dlna.Main
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.Info("Disposing PlayToManager");
|
_logger.LogInformation("Disposing PlayToManager");
|
||||||
_manager.Dispose();
|
_manager.Dispose();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error disposing PlayTo manager", ex);
|
_logger.LogError(ex, "Error disposing PlayTo manager");
|
||||||
}
|
}
|
||||||
_manager = null;
|
_manager = null;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ namespace Emby.Dlna.Main
|
||||||
|
|
||||||
if (_communicationsServer != null)
|
if (_communicationsServer != null)
|
||||||
{
|
{
|
||||||
_logger.Info("Disposing SsdpCommunicationsServer");
|
_logger.LogInformation("Disposing SsdpCommunicationsServer");
|
||||||
_communicationsServer.Dispose();
|
_communicationsServer.Dispose();
|
||||||
_communicationsServer = null;
|
_communicationsServer = null;
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ namespace Emby.Dlna.Main
|
||||||
{
|
{
|
||||||
if (_Publisher != null)
|
if (_Publisher != null)
|
||||||
{
|
{
|
||||||
_logger.Info("Disposing SsdpDevicePublisher");
|
_logger.LogInformation("Disposing SsdpDevicePublisher");
|
||||||
_Publisher.Dispose();
|
_Publisher.Dispose();
|
||||||
_Publisher = null;
|
_Publisher = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using Emby.Dlna.Server;
|
using Emby.Dlna.Server;
|
||||||
using Emby.Dlna.Service;
|
using Emby.Dlna.Service;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MediaBrowser.Model.Xml;
|
using MediaBrowser.Model.Xml;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using Emby.Dlna.Service;
|
using Emby.Dlna.Service;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MediaBrowser.Model.Xml;
|
using MediaBrowser.Model.Xml;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using Emby.Dlna.Common;
|
using Emby.Dlna.Common;
|
||||||
using Emby.Dlna.Ssdp;
|
using Emby.Dlna.Ssdp;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -108,7 +108,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
_logger.Debug("Dlna Device.Start");
|
_logger.LogDebug("Dlna Device.Start");
|
||||||
_timer = _timerFactory.Create(TimerCallback, null, 1000, Timeout.Infinite);
|
_timer = _timerFactory.Create(TimerCallback, null, 1000, Timeout.Infinite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error updating device volume info for {0}", ex, Properties.Name);
|
_logger.LogError(ex, "Error updating device volume info for {DeviceName}", Properties.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Setting mute");
|
_logger.LogDebug("Setting mute");
|
||||||
var value = mute ? 1 : 0;
|
var value = mute ? 1 : 0;
|
||||||
|
|
||||||
await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value))
|
await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value))
|
||||||
|
@ -323,7 +323,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
url = url.Replace("&", "&");
|
url = url.Replace("&", "&");
|
||||||
|
|
||||||
_logger.Debug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", Properties.Name, url, header);
|
_logger.LogDebug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", Properties.Name, url, header);
|
||||||
|
|
||||||
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetAVTransportURI");
|
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetAVTransportURI");
|
||||||
if (command == null)
|
if (command == null)
|
||||||
|
@ -507,7 +507,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//_logger.ErrorException("Error updating device info for {0}", ex, Properties.Name);
|
_logger.LogError(ex, "Error updating device info for {DeviceName}", Properties.Name);
|
||||||
|
|
||||||
_connectFailureCount++;
|
_connectFailureCount++;
|
||||||
|
|
||||||
|
@ -516,7 +516,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
var action = OnDeviceUnavailable;
|
var action = OnDeviceUnavailable;
|
||||||
if (action != null)
|
if (action != null)
|
||||||
{
|
{
|
||||||
_logger.Debug("Disposing device due to loss of connection");
|
_logger.LogDebug("Disposing device due to loss of connection");
|
||||||
action();
|
action();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -767,7 +767,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Unable to parse xml {0}", ex, trackString);
|
_logger.LogError(ex, "Unable to parse xml {0}", trackString);
|
||||||
return new Tuple<bool, uBaseObject>(true, null);
|
return new Tuple<bool, uBaseObject>(true, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -887,7 +887,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl);
|
string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl);
|
||||||
|
|
||||||
var httpClient = new SsdpHttpClient(_httpClient, _config);
|
var httpClient = new SsdpHttpClient(_httpClient, _config);
|
||||||
_logger.Debug("Dlna Device.GetRenderingProtocolAsync");
|
_logger.LogDebug("Dlna Device.GetRenderingProtocolAsync");
|
||||||
var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
|
var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
rendererCommands = TransportCommands.Create(document);
|
rendererCommands = TransportCommands.Create(document);
|
||||||
|
|
|
@ -7,7 +7,7 @@ using Emby.Dlna.Didl;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
using MediaBrowser.Model.System;
|
using MediaBrowser.Model.System;
|
||||||
using System;
|
using System;
|
||||||
|
@ -156,7 +156,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error reporting progress", ex);
|
_logger.LogError(ex, "Error reporting progress");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error reporting playback stopped", ex);
|
_logger.LogError(ex, "Error reporting playback stopped");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error reporting progress", ex);
|
_logger.LogError(ex, "Error reporting progress");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error reporting progress", ex);
|
_logger.LogError(ex, "Error reporting progress");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error reporting progress", ex);
|
_logger.LogError(ex, "Error reporting progress");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
public async Task SendPlayCommand(PlayRequest command, CancellationToken cancellationToken)
|
public async Task SendPlayCommand(PlayRequest command, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.Debug("{0} - Received PlayRequest: {1}", this._session.DeviceName, command.PlayCommand);
|
_logger.LogDebug("{0} - Received PlayRequest: {1}", this._session.DeviceName, command.PlayCommand);
|
||||||
|
|
||||||
var user = command.ControllingUserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(command.ControllingUserId);
|
var user = command.ControllingUserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(command.ControllingUserId);
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("{0} - Playlist created", _session.DeviceName);
|
_logger.LogDebug("{0} - Playlist created", _session.DeviceName);
|
||||||
|
|
||||||
if (command.PlayCommand == PlayCommand.PlayLast)
|
if (command.PlayCommand == PlayCommand.PlayLast)
|
||||||
{
|
{
|
||||||
|
@ -532,23 +532,13 @@ namespace Emby.Dlna.PlayTo
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ILogger GetStreamBuilderLogger()
|
|
||||||
{
|
|
||||||
if (_config.GetDlnaConfiguration().EnableDebugLog)
|
|
||||||
{
|
|
||||||
return _logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NullLogger();
|
|
||||||
}
|
|
||||||
|
|
||||||
private PlaylistItem GetPlaylistItem(BaseItem item, List<MediaSourceInfo> mediaSources, DeviceProfile profile, string deviceId, string mediaSourceId, int? audioStreamIndex, int? subtitleStreamIndex)
|
private PlaylistItem GetPlaylistItem(BaseItem item, List<MediaSourceInfo> mediaSources, DeviceProfile profile, string deviceId, string mediaSourceId, int? audioStreamIndex, int? subtitleStreamIndex)
|
||||||
{
|
{
|
||||||
if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new PlaylistItem
|
return new PlaylistItem
|
||||||
{
|
{
|
||||||
StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildVideoItem(new VideoOptions
|
StreamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildVideoItem(new VideoOptions
|
||||||
{
|
{
|
||||||
ItemId = item.Id,
|
ItemId = item.Id,
|
||||||
MediaSources = mediaSources.ToArray(),
|
MediaSources = mediaSources.ToArray(),
|
||||||
|
@ -568,7 +558,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
{
|
{
|
||||||
return new PlaylistItem
|
return new PlaylistItem
|
||||||
{
|
{
|
||||||
StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildAudioItem(new AudioOptions
|
StreamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildAudioItem(new AudioOptions
|
||||||
{
|
{
|
||||||
ItemId = item.Id,
|
ItemId = item.Id,
|
||||||
MediaSources = mediaSources.ToArray(),
|
MediaSources = mediaSources.ToArray(),
|
||||||
|
@ -599,7 +589,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
{
|
{
|
||||||
Playlist.Clear();
|
Playlist.Clear();
|
||||||
Playlist.AddRange(items);
|
Playlist.AddRange(items);
|
||||||
_logger.Debug("{0} - Playing {1} items", _session.DeviceName, Playlist.Count);
|
_logger.LogDebug("{0} - Playing {1} items", _session.DeviceName, Playlist.Count);
|
||||||
|
|
||||||
await SetPlaylistIndex(0).ConfigureAwait(false);
|
await SetPlaylistIndex(0).ConfigureAwait(false);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -5,7 +5,7 @@ using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -93,7 +93,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1 &&
|
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1 &&
|
||||||
nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1)
|
nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1)
|
||||||
{
|
{
|
||||||
//_logger.Debug("Upnp device {0} does not contain a MediaRenderer device (0).", location);
|
//_logger.LogDebug("Upnp device {0} does not contain a MediaRenderer device (0).", location);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error creating PlayTo device.", ex);
|
_logger.LogError(ex, "Error creating PlayTo device.");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -155,9 +155,9 @@ namespace Emby.Dlna.PlayTo
|
||||||
private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken)
|
private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var uri = info.Location;
|
var uri = info.Location;
|
||||||
_logger.Debug("Attempting to create PlayToController from location {0}", location);
|
_logger.LogDebug("Attempting to create PlayToController from location {0}", location);
|
||||||
|
|
||||||
_logger.Debug("Logging session activity from location {0}", location);
|
_logger.LogDebug("Logging session activity from location {0}", location);
|
||||||
string uuid;
|
string uuid;
|
||||||
if (info.Headers.TryGetValue("USN", out uuid))
|
if (info.Headers.TryGetValue("USN", out uuid))
|
||||||
{
|
{
|
||||||
|
@ -237,7 +237,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
SupportsMediaControl = true
|
SupportsMediaControl = true
|
||||||
});
|
});
|
||||||
|
|
||||||
_logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
|
_logger.LogInformation("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using Emby.Dlna.Server;
|
using Emby.Dlna.Server;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -20,13 +20,13 @@ namespace Emby.Dlna.Service
|
||||||
private const string NS_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/";
|
private const string NS_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/";
|
||||||
|
|
||||||
protected readonly IServerConfigurationManager Config;
|
protected readonly IServerConfigurationManager Config;
|
||||||
protected readonly ILogger Logger;
|
protected readonly ILogger _logger;
|
||||||
protected readonly IXmlReaderSettingsFactory XmlReaderSettingsFactory;
|
protected readonly IXmlReaderSettingsFactory XmlReaderSettingsFactory;
|
||||||
|
|
||||||
protected BaseControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
|
protected BaseControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
|
||||||
{
|
{
|
||||||
Config = config;
|
Config = config;
|
||||||
Logger = logger;
|
_logger = logger;
|
||||||
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
|
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ namespace Emby.Dlna.Service
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error processing control request", ex);
|
_logger.LogError(ex, "Error processing control request");
|
||||||
|
|
||||||
return new ControlErrorHandler().GetResponse(ex);
|
return new ControlErrorHandler().GetResponse(ex);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ namespace Emby.Dlna.Service
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug("Received control request {0}", requestInfo.LocalName);
|
_logger.LogDebug("Received control request {0}", requestInfo.LocalName);
|
||||||
|
|
||||||
var result = GetResult(requestInfo.LocalName, requestInfo.Headers);
|
var result = GetResult(requestInfo.LocalName, requestInfo.Headers);
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ namespace Emby.Dlna.Service
|
||||||
IsSuccessful = true
|
IsSuccessful = true
|
||||||
};
|
};
|
||||||
|
|
||||||
//Logger.Debug(xml);
|
//logger.LogDebug(xml);
|
||||||
|
|
||||||
controlResponse.Headers.Add("EXT", string.Empty);
|
controlResponse.Headers.Add("EXT", string.Empty);
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ namespace Emby.Dlna.Service
|
||||||
var originalHeaders = request.Headers;
|
var originalHeaders = request.Headers;
|
||||||
var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
|
var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
|
||||||
|
|
||||||
Logger.Debug("Control request. Headers: {0}", headers);
|
_logger.LogDebug("Control request. Headers: {0}", headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LogResponse(ControlResponse response)
|
private void LogResponse(ControlResponse response)
|
||||||
|
@ -258,7 +258,7 @@ namespace Emby.Dlna.Service
|
||||||
var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
|
var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
|
||||||
//builder.Append(response.Xml);
|
//builder.Append(response.Xml);
|
||||||
|
|
||||||
Logger.Debug("Control response. Headers: {0}", headers);
|
_logger.LogDebug("Control response. Headers: {0}", headers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using Emby.Dlna.Eventing;
|
using Emby.Dlna.Eventing;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Dlna.Service
|
namespace Emby.Dlna.Service
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -119,7 +119,7 @@ namespace Emby.Dlna.Ssdp
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EventHelper.FireEventIfNotNull(DeviceDiscoveredInternal, this, args, _logger);
|
DeviceDiscoveredInternal?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _DeviceLocator_DeviceUnavailable(object sender, DeviceUnavailableEventArgs e)
|
private void _DeviceLocator_DeviceUnavailable(object sender, DeviceUnavailableEventArgs e)
|
||||||
|
@ -139,7 +139,7 @@ namespace Emby.Dlna.Ssdp
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EventHelper.FireEventIfNotNull(DeviceLeft, this, args, _logger);
|
DeviceLeft?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\ImageMagickSharp\ImageMagickSharp\ImageMagickSharp.csproj" />
|
|
||||||
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
|
|
||||||
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
|
|
||||||
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="fonts\robotoregular.ttf" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,43 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.ImageMagick
|
|
||||||
{
|
|
||||||
internal static class ImageHelpers
|
|
||||||
{
|
|
||||||
internal static List<string> ProjectPaths(string[] paths, int count)
|
|
||||||
{
|
|
||||||
if (count <= 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException("count");
|
|
||||||
}
|
|
||||||
if (paths.Length == 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException("paths");
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = new List<string>();
|
|
||||||
|
|
||||||
AddToList(list, paths, count);
|
|
||||||
|
|
||||||
return list.Take(count).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddToList(List<string> list, string[] paths, int count)
|
|
||||||
{
|
|
||||||
while (list.Count < count)
|
|
||||||
{
|
|
||||||
foreach (var path in paths)
|
|
||||||
{
|
|
||||||
list.Add(path);
|
|
||||||
|
|
||||||
if (list.Count >= count)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,354 +0,0 @@
|
||||||
using System.Threading.Tasks;
|
|
||||||
using ImageMagickSharp;
|
|
||||||
using MediaBrowser.Common.Configuration;
|
|
||||||
using MediaBrowser.Common.Net;
|
|
||||||
using MediaBrowser.Controller.Drawing;
|
|
||||||
using MediaBrowser.Model.Drawing;
|
|
||||||
using MediaBrowser.Model.Logging;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using MediaBrowser.Model.System;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.ImageMagick
|
|
||||||
{
|
|
||||||
public class ImageMagickEncoder : IImageEncoder, IDisposable
|
|
||||||
{
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
private readonly IApplicationPaths _appPaths;
|
|
||||||
private readonly Func<IHttpClient> _httpClientFactory;
|
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
private readonly IEnvironmentInfo _environment;
|
|
||||||
|
|
||||||
public ImageMagickEncoder(ILogger logger, IApplicationPaths appPaths, Func<IHttpClient> httpClientFactory, IFileSystem fileSystem, IEnvironmentInfo environment)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_appPaths = appPaths;
|
|
||||||
_httpClientFactory = httpClientFactory;
|
|
||||||
_fileSystem = fileSystem;
|
|
||||||
_environment = environment;
|
|
||||||
|
|
||||||
LogVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string[] SupportedInputFormats
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
// Some common file name extensions for RAW picture files include: .cr2, .crw, .dng, .nef, .orf, .rw2, .pef, .arw, .sr2, .srf, and .tif.
|
|
||||||
return new[]
|
|
||||||
{
|
|
||||||
"tiff",
|
|
||||||
"tif",
|
|
||||||
"jpeg",
|
|
||||||
"jpg",
|
|
||||||
"png",
|
|
||||||
"aiff",
|
|
||||||
"cr2",
|
|
||||||
"crw",
|
|
||||||
"dng",
|
|
||||||
|
|
||||||
// Remove until supported
|
|
||||||
//"nef",
|
|
||||||
"orf",
|
|
||||||
"pef",
|
|
||||||
"arw",
|
|
||||||
"webp",
|
|
||||||
"gif",
|
|
||||||
"bmp",
|
|
||||||
"erf",
|
|
||||||
"raf",
|
|
||||||
"rw2",
|
|
||||||
"nrw"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImageFormat[] SupportedOutputFormats
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_webpAvailable)
|
|
||||||
{
|
|
||||||
return new[] { ImageFormat.Webp, ImageFormat.Gif, ImageFormat.Jpg, ImageFormat.Png };
|
|
||||||
}
|
|
||||||
return new[] { ImageFormat.Gif, ImageFormat.Jpg, ImageFormat.Png };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogVersion()
|
|
||||||
{
|
|
||||||
_logger.Info("ImageMagick version: " + GetVersion());
|
|
||||||
TestWebp();
|
|
||||||
Wand.SetMagickThreadCount(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetVersion()
|
|
||||||
{
|
|
||||||
return Wand.VersionString;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _webpAvailable = true;
|
|
||||||
private void TestWebp()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var tmpPath = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".webp");
|
|
||||||
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(tmpPath));
|
|
||||||
|
|
||||||
using (var wand = new MagickWand(1, 1, new PixelWand("none", 1)))
|
|
||||||
{
|
|
||||||
wand.SaveImage(tmpPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
//_logger.ErrorException("Error loading webp: ", ex);
|
|
||||||
_webpAvailable = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImageSize GetImageSize(string path)
|
|
||||||
{
|
|
||||||
CheckDisposed();
|
|
||||||
|
|
||||||
using (var wand = new MagickWand())
|
|
||||||
{
|
|
||||||
wand.PingImage(path);
|
|
||||||
var img = wand.CurrentImage;
|
|
||||||
|
|
||||||
return new ImageSize
|
|
||||||
{
|
|
||||||
Width = img.Width,
|
|
||||||
Height = img.Height
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HasTransparency(string path)
|
|
||||||
{
|
|
||||||
var ext = Path.GetExtension(path);
|
|
||||||
|
|
||||||
return string.Equals(ext, ".png", StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
|
|
||||||
{
|
|
||||||
// Even if the caller specified 100, don't use it because it takes forever
|
|
||||||
quality = Math.Min(quality, 99);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(options.BackgroundColor) || !HasTransparency(inputPath))
|
|
||||||
{
|
|
||||||
using (var originalImage = new MagickWand(inputPath))
|
|
||||||
{
|
|
||||||
if (options.CropWhiteSpace)
|
|
||||||
{
|
|
||||||
originalImage.CurrentImage.TrimImage(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
var originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height);
|
|
||||||
|
|
||||||
if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize) && !autoOrient)
|
|
||||||
{
|
|
||||||
// Just spit out the original file if all the options are default
|
|
||||||
return inputPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize);
|
|
||||||
|
|
||||||
var width = Convert.ToInt32(Math.Round(newImageSize.Width));
|
|
||||||
var height = Convert.ToInt32(Math.Round(newImageSize.Height));
|
|
||||||
|
|
||||||
ScaleImage(originalImage, width, height, options.Blur ?? 0);
|
|
||||||
|
|
||||||
if (autoOrient)
|
|
||||||
{
|
|
||||||
AutoOrientImage(originalImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddForegroundLayer(originalImage, options);
|
|
||||||
DrawIndicator(originalImage, width, height, options);
|
|
||||||
|
|
||||||
originalImage.CurrentImage.CompressionQuality = quality;
|
|
||||||
originalImage.CurrentImage.StripImage();
|
|
||||||
|
|
||||||
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(outputPath));
|
|
||||||
|
|
||||||
originalImage.SaveImage(outputPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
using (var originalImage = new MagickWand(inputPath))
|
|
||||||
{
|
|
||||||
var originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height);
|
|
||||||
|
|
||||||
var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize);
|
|
||||||
|
|
||||||
var width = Convert.ToInt32(Math.Round(newImageSize.Width));
|
|
||||||
var height = Convert.ToInt32(Math.Round(newImageSize.Height));
|
|
||||||
|
|
||||||
using (var wand = new MagickWand(width, height, options.BackgroundColor))
|
|
||||||
{
|
|
||||||
ScaleImage(originalImage, width, height, options.Blur ?? 0);
|
|
||||||
|
|
||||||
if (autoOrient)
|
|
||||||
{
|
|
||||||
AutoOrientImage(originalImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0);
|
|
||||||
|
|
||||||
AddForegroundLayer(wand, options);
|
|
||||||
DrawIndicator(wand, width, height, options);
|
|
||||||
|
|
||||||
wand.CurrentImage.CompressionQuality = quality;
|
|
||||||
wand.CurrentImage.StripImage();
|
|
||||||
|
|
||||||
wand.SaveImage(outputPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return outputPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(options.ForegroundLayer))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Double opacity;
|
|
||||||
if (!Double.TryParse(options.ForegroundLayer, out opacity)) opacity = .4;
|
|
||||||
|
|
||||||
using (var pixel = new PixelWand("#000", opacity))
|
|
||||||
using (var overlay = new MagickWand(wand.CurrentImage.Width, wand.CurrentImage.Height, pixel))
|
|
||||||
{
|
|
||||||
wand.CurrentImage.CompositeImage(overlay, CompositeOperator.OverCompositeOp, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AutoOrientImage(MagickWand wand)
|
|
||||||
{
|
|
||||||
wand.CurrentImage.AutoOrientImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RotateImage(MagickWand wand, float angle)
|
|
||||||
{
|
|
||||||
using (var pixelWand = new PixelWand("none", 1))
|
|
||||||
{
|
|
||||||
wand.CurrentImage.RotateImage(pixelWand, angle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ScaleImage(MagickWand wand, int width, int height, int blur)
|
|
||||||
{
|
|
||||||
var useResize = blur > 1;
|
|
||||||
|
|
||||||
if (useResize)
|
|
||||||
{
|
|
||||||
wand.CurrentImage.ResizeImage(width, height, FilterTypes.GaussianFilter, blur);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wand.CurrentImage.ScaleImage(width, height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Draws the indicator.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="wand">The wand.</param>
|
|
||||||
/// <param name="imageWidth">Width of the image.</param>
|
|
||||||
/// <param name="imageHeight">Height of the image.</param>
|
|
||||||
/// <param name="options">The options.</param>
|
|
||||||
private void DrawIndicator(MagickWand wand, int imageWidth, int imageHeight, ImageProcessingOptions options)
|
|
||||||
{
|
|
||||||
if (!options.AddPlayedIndicator && !options.UnplayedCount.HasValue && options.PercentPlayed.Equals(0))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (options.AddPlayedIndicator)
|
|
||||||
{
|
|
||||||
var currentImageSize = new ImageSize(imageWidth, imageHeight);
|
|
||||||
|
|
||||||
var task = new PlayedIndicatorDrawer(_appPaths, _httpClientFactory(), _fileSystem).DrawPlayedIndicator(wand, currentImageSize);
|
|
||||||
Task.WaitAll(task);
|
|
||||||
}
|
|
||||||
else if (options.UnplayedCount.HasValue)
|
|
||||||
{
|
|
||||||
var currentImageSize = new ImageSize(imageWidth, imageHeight);
|
|
||||||
|
|
||||||
new UnplayedCountIndicator(_appPaths, _fileSystem).DrawUnplayedCountIndicator(wand, currentImageSize, options.UnplayedCount.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.PercentPlayed > 0)
|
|
||||||
{
|
|
||||||
new PercentPlayedDrawer().Process(wand, options.PercentPlayed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.ErrorException("Error drawing indicator overlay", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateImageCollage(ImageCollageOptions options)
|
|
||||||
{
|
|
||||||
double ratio = options.Width;
|
|
||||||
ratio /= options.Height;
|
|
||||||
|
|
||||||
if (ratio >= 1.4)
|
|
||||||
{
|
|
||||||
new StripCollageBuilder(_appPaths, _fileSystem).BuildThumbCollage(options.InputPaths, options.OutputPath, options.Width, options.Height);
|
|
||||||
}
|
|
||||||
else if (ratio >= .9)
|
|
||||||
{
|
|
||||||
new StripCollageBuilder(_appPaths, _fileSystem).BuildSquareCollage(options.InputPaths, options.OutputPath, options.Width, options.Height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths, options.OutputPath, options.Width, options.Height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "ImageMagick"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _disposed;
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_disposed = true;
|
|
||||||
Wand.CloseEnvironment();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckDisposed()
|
|
||||||
{
|
|
||||||
if (_disposed)
|
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(GetType().Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SupportsImageCollageCreation
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SupportsImageEncoding
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
using ImageMagickSharp;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.ImageMagick
|
|
||||||
{
|
|
||||||
public class PercentPlayedDrawer
|
|
||||||
{
|
|
||||||
private const int IndicatorHeight = 8;
|
|
||||||
|
|
||||||
public void Process(MagickWand wand, double percent)
|
|
||||||
{
|
|
||||||
var currentImage = wand.CurrentImage;
|
|
||||||
var height = currentImage.Height;
|
|
||||||
|
|
||||||
using (var draw = new DrawingWand())
|
|
||||||
{
|
|
||||||
using (PixelWand pixel = new PixelWand())
|
|
||||||
{
|
|
||||||
var endX = currentImage.Width - 1;
|
|
||||||
var endY = height - 1;
|
|
||||||
|
|
||||||
pixel.Color = "black";
|
|
||||||
pixel.Opacity = 0.4;
|
|
||||||
draw.FillColor = pixel;
|
|
||||||
draw.DrawRectangle(0, endY - IndicatorHeight, endX, endY);
|
|
||||||
|
|
||||||
double foregroundWidth = endX;
|
|
||||||
foregroundWidth *= percent;
|
|
||||||
foregroundWidth /= 100;
|
|
||||||
|
|
||||||
pixel.Color = "#52B54B";
|
|
||||||
pixel.Opacity = 0;
|
|
||||||
draw.FillColor = pixel;
|
|
||||||
draw.DrawRectangle(0, endY - IndicatorHeight, Convert.ToInt32(Math.Round(foregroundWidth)), endY);
|
|
||||||
wand.CurrentImage.DrawImage(draw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
using ImageMagickSharp;
|
|
||||||
using MediaBrowser.Common.Configuration;
|
|
||||||
using MediaBrowser.Common.Net;
|
|
||||||
using MediaBrowser.Model.Drawing;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediaBrowser.Common.Progress;
|
|
||||||
using MediaBrowser.Controller.IO;
|
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.ImageMagick
|
|
||||||
{
|
|
||||||
public class PlayedIndicatorDrawer
|
|
||||||
{
|
|
||||||
private const int FontSize = 52;
|
|
||||||
private const int OffsetFromTopRightCorner = 38;
|
|
||||||
|
|
||||||
private readonly IApplicationPaths _appPaths;
|
|
||||||
private readonly IHttpClient _iHttpClient;
|
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
|
|
||||||
public PlayedIndicatorDrawer(IApplicationPaths appPaths, IHttpClient iHttpClient, IFileSystem fileSystem)
|
|
||||||
{
|
|
||||||
_appPaths = appPaths;
|
|
||||||
_iHttpClient = iHttpClient;
|
|
||||||
_fileSystem = fileSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DrawPlayedIndicator(MagickWand wand, ImageSize imageSize)
|
|
||||||
{
|
|
||||||
var x = imageSize.Width - OffsetFromTopRightCorner;
|
|
||||||
|
|
||||||
using (var draw = new DrawingWand())
|
|
||||||
{
|
|
||||||
using (PixelWand pixel = new PixelWand())
|
|
||||||
{
|
|
||||||
pixel.Color = "#52B54B";
|
|
||||||
pixel.Opacity = 0.2;
|
|
||||||
draw.FillColor = pixel;
|
|
||||||
draw.DrawCircle(x, OffsetFromTopRightCorner, x - 20, OffsetFromTopRightCorner - 20);
|
|
||||||
|
|
||||||
pixel.Opacity = 0;
|
|
||||||
pixel.Color = "white";
|
|
||||||
draw.FillColor = pixel;
|
|
||||||
draw.Font = await DownloadFont("webdings.ttf", "https://github.com/MediaBrowser/Emby.Resources/raw/master/fonts/webdings.ttf", _appPaths, _iHttpClient, _fileSystem).ConfigureAwait(false);
|
|
||||||
draw.FontSize = FontSize;
|
|
||||||
draw.FontStyle = FontStyleType.NormalStyle;
|
|
||||||
draw.TextAlignment = TextAlignType.CenterAlign;
|
|
||||||
draw.FontWeight = FontWeightType.RegularStyle;
|
|
||||||
draw.TextAntialias = true;
|
|
||||||
draw.DrawAnnotation(x + 4, OffsetFromTopRightCorner + 14, "a");
|
|
||||||
|
|
||||||
draw.FillColor = pixel;
|
|
||||||
wand.CurrentImage.DrawImage(draw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static string ExtractFont(string name, IApplicationPaths paths, IFileSystem fileSystem)
|
|
||||||
{
|
|
||||||
var filePath = Path.Combine(paths.ProgramDataPath, "fonts", name);
|
|
||||||
|
|
||||||
if (fileSystem.FileExists(filePath))
|
|
||||||
{
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
var namespacePath = typeof(PlayedIndicatorDrawer).Namespace + ".fonts." + name;
|
|
||||||
var tempPath = Path.Combine(paths.TempDirectory, Guid.NewGuid().ToString("N") + ".ttf");
|
|
||||||
fileSystem.CreateDirectory(fileSystem.GetDirectoryName(tempPath));
|
|
||||||
|
|
||||||
using (var stream = typeof(PlayedIndicatorDrawer).Assembly.GetManifestResourceStream(namespacePath))
|
|
||||||
{
|
|
||||||
using (var fileStream = new FileStream(tempPath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
|
||||||
{
|
|
||||||
stream.CopyTo(fileStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileSystem.CreateDirectory(fileSystem.GetDirectoryName(filePath));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
fileSystem.CopyFile(tempPath, filePath, false);
|
|
||||||
}
|
|
||||||
catch (IOException)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return tempPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static async Task<string> DownloadFont(string name, string url, IApplicationPaths paths, IHttpClient httpClient, IFileSystem fileSystem)
|
|
||||||
{
|
|
||||||
var filePath = Path.Combine(paths.ProgramDataPath, "fonts", name);
|
|
||||||
|
|
||||||
if (fileSystem.FileExists(filePath))
|
|
||||||
{
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tempPath = await httpClient.GetTempFile(new HttpRequestOptions
|
|
||||||
{
|
|
||||||
Url = url,
|
|
||||||
Progress = new SimpleProgress<double>()
|
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
|
||||||
|
|
||||||
fileSystem.CreateDirectory(fileSystem.GetDirectoryName(filePath));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
fileSystem.CopyFile(tempPath, filePath, false);
|
|
||||||
}
|
|
||||||
catch (IOException)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return tempPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("Emby.Drawing.ImageMagick")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("")]
|
|
||||||
[assembly: AssemblyProduct("Emby.Drawing.ImageMagick")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("6cfee013-6e7c-432b-ac37-cabf0880c69a")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
|
||||||
// by using the '*' as shown below:
|
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
|
||||||
[assembly: AssemblyVersion("1.0.0.0")]
|
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
|
@ -1,202 +0,0 @@
|
||||||
using ImageMagickSharp;
|
|
||||||
using MediaBrowser.Common.Configuration;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
using MediaBrowser.Controller.IO;
|
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.ImageMagick
|
|
||||||
{
|
|
||||||
public class StripCollageBuilder
|
|
||||||
{
|
|
||||||
private readonly IApplicationPaths _appPaths;
|
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
|
|
||||||
public StripCollageBuilder(IApplicationPaths appPaths, IFileSystem fileSystem)
|
|
||||||
{
|
|
||||||
_appPaths = appPaths;
|
|
||||||
_fileSystem = fileSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BuildPosterCollage(string[] paths, string outputPath, int width, int height)
|
|
||||||
{
|
|
||||||
using (var wand = BuildPosterCollageWand(paths, width, height))
|
|
||||||
{
|
|
||||||
wand.SaveImage(outputPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BuildSquareCollage(string[] paths, string outputPath, int width, int height)
|
|
||||||
{
|
|
||||||
using (var wand = BuildSquareCollageWand(paths, width, height))
|
|
||||||
{
|
|
||||||
wand.SaveImage(outputPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BuildThumbCollage(string[] paths, string outputPath, int width, int height)
|
|
||||||
{
|
|
||||||
using (var wand = BuildThumbCollageWand(paths, width, height))
|
|
||||||
{
|
|
||||||
wand.SaveImage(outputPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MagickWand BuildPosterCollageWand(string[] paths, int width, int height)
|
|
||||||
{
|
|
||||||
var inputPaths = ImageHelpers.ProjectPaths(paths, 3);
|
|
||||||
using (var wandImages = new MagickWand(inputPaths.ToArray()))
|
|
||||||
{
|
|
||||||
var wand = new MagickWand(width, height);
|
|
||||||
wand.OpenImage("gradient:#111111-#111111");
|
|
||||||
using (var draw = new DrawingWand())
|
|
||||||
{
|
|
||||||
var iSlice = Convert.ToInt32(width * 0.3);
|
|
||||||
int iTrans = Convert.ToInt32(height * .25);
|
|
||||||
int iHeight = Convert.ToInt32(height * .65);
|
|
||||||
var horizontalImagePadding = Convert.ToInt32(width * 0.0366);
|
|
||||||
|
|
||||||
foreach (var element in wandImages.ImageList)
|
|
||||||
{
|
|
||||||
using (var blackPixelWand = new PixelWand(ColorName.Black))
|
|
||||||
{
|
|
||||||
int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
|
|
||||||
element.Gravity = GravityType.CenterGravity;
|
|
||||||
element.BackgroundColor = blackPixelWand;
|
|
||||||
element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
|
|
||||||
int ix = (int)Math.Abs((iWidth - iSlice) / 2);
|
|
||||||
element.CropImage(iSlice, iHeight, ix, 0);
|
|
||||||
|
|
||||||
element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wandImages.SetFirstIterator();
|
|
||||||
using (var wandList = wandImages.AppendImages())
|
|
||||||
{
|
|
||||||
wandList.CurrentImage.TrimImage(1);
|
|
||||||
using (var mwr = wandList.CloneMagickWand())
|
|
||||||
{
|
|
||||||
using (var blackPixelWand = new PixelWand(ColorName.Black))
|
|
||||||
{
|
|
||||||
using (var greyPixelWand = new PixelWand(ColorName.Grey70))
|
|
||||||
{
|
|
||||||
mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
|
|
||||||
mwr.CurrentImage.FlipImage();
|
|
||||||
|
|
||||||
mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
|
|
||||||
mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
|
|
||||||
|
|
||||||
using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
|
|
||||||
{
|
|
||||||
mwg.OpenImage("gradient:black-none");
|
|
||||||
var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
|
|
||||||
mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.CopyOpacityCompositeOp, 0, verticalSpacing);
|
|
||||||
|
|
||||||
wandList.AddImage(mwr);
|
|
||||||
int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
|
|
||||||
wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .05));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MagickWand BuildThumbCollageWand(string[] paths, int width, int height)
|
|
||||||
{
|
|
||||||
var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
|
|
||||||
using (var wandImages = new MagickWand(inputPaths.ToArray()))
|
|
||||||
{
|
|
||||||
var wand = new MagickWand(width, height);
|
|
||||||
wand.OpenImage("gradient:#111111-#111111");
|
|
||||||
using (var draw = new DrawingWand())
|
|
||||||
{
|
|
||||||
var iSlice = Convert.ToInt32(width * 0.24125);
|
|
||||||
int iTrans = Convert.ToInt32(height * .25);
|
|
||||||
int iHeight = Convert.ToInt32(height * .70);
|
|
||||||
var horizontalImagePadding = Convert.ToInt32(width * 0.0125);
|
|
||||||
|
|
||||||
foreach (var element in wandImages.ImageList)
|
|
||||||
{
|
|
||||||
using (var blackPixelWand = new PixelWand(ColorName.Black))
|
|
||||||
{
|
|
||||||
int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
|
|
||||||
element.Gravity = GravityType.CenterGravity;
|
|
||||||
element.BackgroundColor = blackPixelWand;
|
|
||||||
element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
|
|
||||||
int ix = (int)Math.Abs((iWidth - iSlice) / 2);
|
|
||||||
element.CropImage(iSlice, iHeight, ix, 0);
|
|
||||||
|
|
||||||
element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wandImages.SetFirstIterator();
|
|
||||||
using (var wandList = wandImages.AppendImages())
|
|
||||||
{
|
|
||||||
wandList.CurrentImage.TrimImage(1);
|
|
||||||
using (var mwr = wandList.CloneMagickWand())
|
|
||||||
{
|
|
||||||
using (var blackPixelWand = new PixelWand(ColorName.Black))
|
|
||||||
{
|
|
||||||
using (var greyPixelWand = new PixelWand(ColorName.Grey70))
|
|
||||||
{
|
|
||||||
mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
|
|
||||||
mwr.CurrentImage.FlipImage();
|
|
||||||
|
|
||||||
mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
|
|
||||||
mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
|
|
||||||
|
|
||||||
using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
|
|
||||||
{
|
|
||||||
mwg.OpenImage("gradient:black-none");
|
|
||||||
var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
|
|
||||||
mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.CopyOpacityCompositeOp, 0, verticalSpacing);
|
|
||||||
|
|
||||||
wandList.AddImage(mwr);
|
|
||||||
int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
|
|
||||||
wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .045));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MagickWand BuildSquareCollageWand(string[] paths, int width, int height)
|
|
||||||
{
|
|
||||||
var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
|
|
||||||
var outputWand = new MagickWand(width, height, new PixelWand("none", 1));
|
|
||||||
var imageIndex = 0;
|
|
||||||
var cellWidth = width/2;
|
|
||||||
var cellHeight = height/2;
|
|
||||||
for (var x = 0; x < 2; x++)
|
|
||||||
{
|
|
||||||
for (var y = 0; y < 2; y++)
|
|
||||||
{
|
|
||||||
using (var temp = new MagickWand(inputPaths[imageIndex]))
|
|
||||||
{
|
|
||||||
temp.CurrentImage.ScaleImage(cellWidth, cellHeight);
|
|
||||||
// draw this image into the strip at the next position
|
|
||||||
var xPos = x*cellWidth;
|
|
||||||
var yPos = y*cellHeight;
|
|
||||||
outputWand.CurrentImage.CompositeImage(temp, CompositeOperator.OverCompositeOp, xPos, yPos);
|
|
||||||
}
|
|
||||||
imageIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return outputWand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
using ImageMagickSharp;
|
|
||||||
using MediaBrowser.Common.Configuration;
|
|
||||||
using MediaBrowser.Model.Drawing;
|
|
||||||
using System.Globalization;
|
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.ImageMagick
|
|
||||||
{
|
|
||||||
public class UnplayedCountIndicator
|
|
||||||
{
|
|
||||||
private const int OffsetFromTopRightCorner = 38;
|
|
||||||
|
|
||||||
private readonly IApplicationPaths _appPaths;
|
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
|
|
||||||
public UnplayedCountIndicator(IApplicationPaths appPaths, IFileSystem fileSystem)
|
|
||||||
{
|
|
||||||
_appPaths = appPaths;
|
|
||||||
_fileSystem = fileSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DrawUnplayedCountIndicator(MagickWand wand, ImageSize imageSize, int count)
|
|
||||||
{
|
|
||||||
var x = imageSize.Width - OffsetFromTopRightCorner;
|
|
||||||
var text = count.ToString(CultureInfo.InvariantCulture);
|
|
||||||
|
|
||||||
using (var draw = new DrawingWand())
|
|
||||||
{
|
|
||||||
using (PixelWand pixel = new PixelWand())
|
|
||||||
{
|
|
||||||
pixel.Color = "#52B54B";
|
|
||||||
pixel.Opacity = 0.2;
|
|
||||||
draw.FillColor = pixel;
|
|
||||||
draw.DrawCircle(x, OffsetFromTopRightCorner, x - 20, OffsetFromTopRightCorner - 20);
|
|
||||||
|
|
||||||
pixel.Opacity = 0;
|
|
||||||
pixel.Color = "white";
|
|
||||||
draw.FillColor = pixel;
|
|
||||||
draw.Font = PlayedIndicatorDrawer.ExtractFont("robotoregular.ttf", _appPaths, _fileSystem);
|
|
||||||
draw.FontStyle = FontStyleType.NormalStyle;
|
|
||||||
draw.TextAlignment = TextAlignType.CenterAlign;
|
|
||||||
draw.FontWeight = FontWeightType.RegularStyle;
|
|
||||||
draw.TextAntialias = true;
|
|
||||||
|
|
||||||
var fontSize = 30;
|
|
||||||
var y = OffsetFromTopRightCorner + 11;
|
|
||||||
|
|
||||||
if (text.Length == 1)
|
|
||||||
{
|
|
||||||
x += 1;
|
|
||||||
}
|
|
||||||
else if (text.Length == 2)
|
|
||||||
{
|
|
||||||
x += 1;
|
|
||||||
}
|
|
||||||
else if (text.Length >= 3)
|
|
||||||
{
|
|
||||||
//x += 1;
|
|
||||||
y -= 2;
|
|
||||||
fontSize = 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw.FontSize = fontSize;
|
|
||||||
draw.DrawAnnotation(x, y, text);
|
|
||||||
|
|
||||||
draw.FillColor = pixel;
|
|
||||||
wand.CurrentImage.DrawImage(draw);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using System.IO;
|
|
||||||
using MediaBrowser.Common.IO;
|
|
||||||
using MediaBrowser.Controller.IO;
|
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.Net
|
|
||||||
{
|
|
||||||
public static class DynamicImageHelpers
|
|
||||||
{
|
|
||||||
public static void CreateThumbCollage(List<string> files,
|
|
||||||
IFileSystem fileSystem,
|
|
||||||
string file,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
const int numStrips = 4;
|
|
||||||
files = ImageHelpers.ProjectPaths(files, numStrips);
|
|
||||||
|
|
||||||
const int rows = 1;
|
|
||||||
int cols = numStrips;
|
|
||||||
|
|
||||||
int cellWidth = 2 * (width / 3);
|
|
||||||
int cellHeight = height;
|
|
||||||
var index = 0;
|
|
||||||
|
|
||||||
using (var img = new Bitmap(width, height, PixelFormat.Format32bppPArgb))
|
|
||||||
{
|
|
||||||
using (var graphics = Graphics.FromImage(img))
|
|
||||||
{
|
|
||||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
|
||||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
|
||||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
||||||
|
|
||||||
// SourceCopy causes the image to be blank in OSX
|
|
||||||
//graphics.CompositingMode = CompositingMode.SourceCopy;
|
|
||||||
|
|
||||||
for (var row = 0; row < rows; row++)
|
|
||||||
{
|
|
||||||
for (var col = 0; col < cols; col++)
|
|
||||||
{
|
|
||||||
var x = col * (cellWidth / 2);
|
|
||||||
var y = row * cellHeight;
|
|
||||||
|
|
||||||
if (files.Count > index)
|
|
||||||
{
|
|
||||||
using (var imgtemp = Image.FromFile(files[index]))
|
|
||||||
{
|
|
||||||
graphics.DrawImage(imgtemp, x, y, cellWidth, cellHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
img.Save(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CreateSquareCollage(List<string> files,
|
|
||||||
IFileSystem fileSystem,
|
|
||||||
string file,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
files = ImageHelpers.ProjectPaths(files, 4);
|
|
||||||
|
|
||||||
const int rows = 2;
|
|
||||||
const int cols = 2;
|
|
||||||
|
|
||||||
int singleSize = width / 2;
|
|
||||||
var index = 0;
|
|
||||||
|
|
||||||
using (var img = new Bitmap(width, height, PixelFormat.Format32bppPArgb))
|
|
||||||
{
|
|
||||||
using (var graphics = Graphics.FromImage(img))
|
|
||||||
{
|
|
||||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
|
||||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
|
||||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
||||||
|
|
||||||
// SourceCopy causes the image to be blank in OSX
|
|
||||||
//graphics.CompositingMode = CompositingMode.SourceCopy;
|
|
||||||
|
|
||||||
for (var row = 0; row < rows; row++)
|
|
||||||
{
|
|
||||||
for (var col = 0; col < cols; col++)
|
|
||||||
{
|
|
||||||
var x = col * singleSize;
|
|
||||||
var y = row * singleSize;
|
|
||||||
|
|
||||||
using (var imgtemp = Image.FromFile(files[index]))
|
|
||||||
{
|
|
||||||
graphics.DrawImage(imgtemp, x, y, singleSize, singleSize);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
img.Save(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
|
|
||||||
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
|
|
||||||
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="empty.png" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,282 +0,0 @@
|
||||||
using MediaBrowser.Controller.Drawing;
|
|
||||||
using MediaBrowser.Model.Drawing;
|
|
||||||
using MediaBrowser.Model.Logging;
|
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using MediaBrowser.Common.IO;
|
|
||||||
using MediaBrowser.Controller.IO;
|
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using ImageFormat = MediaBrowser.Model.Drawing.ImageFormat;
|
|
||||||
using Emby.Drawing;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.Net
|
|
||||||
{
|
|
||||||
public class GDIImageEncoder : IImageEncoder
|
|
||||||
{
|
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
|
|
||||||
public GDIImageEncoder(IFileSystem fileSystem, ILogger logger)
|
|
||||||
{
|
|
||||||
_fileSystem = fileSystem;
|
|
||||||
_logger = logger;
|
|
||||||
|
|
||||||
LogInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogInfo()
|
|
||||||
{
|
|
||||||
_logger.Info("GDIImageEncoder starting");
|
|
||||||
using (var stream = GetType().Assembly.GetManifestResourceStream(GetType().Namespace + ".empty.png"))
|
|
||||||
{
|
|
||||||
using (var img = Image.FromStream(stream))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_logger.Info("GDIImageEncoder started");
|
|
||||||
}
|
|
||||||
|
|
||||||
public string[] SupportedInputFormats
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new[]
|
|
||||||
{
|
|
||||||
"png",
|
|
||||||
"jpeg",
|
|
||||||
"jpg",
|
|
||||||
"gif",
|
|
||||||
"bmp"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImageFormat[] SupportedOutputFormats
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new[] { ImageFormat.Gif, ImageFormat.Jpg, ImageFormat.Png };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImageSize GetImageSize(string path)
|
|
||||||
{
|
|
||||||
using (var image = Image.FromFile(path))
|
|
||||||
{
|
|
||||||
return new ImageSize
|
|
||||||
{
|
|
||||||
Width = image.Width,
|
|
||||||
Height = image.Height
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Image GetImage(string path, bool cropWhitespace)
|
|
||||||
{
|
|
||||||
if (cropWhitespace)
|
|
||||||
{
|
|
||||||
using (var originalImage = (Bitmap)Image.FromFile(path))
|
|
||||||
{
|
|
||||||
return originalImage.CropWhitespace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Image.FromFile(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EncodeImage(string inputPath, ImageSize? originalImageSize, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
|
|
||||||
{
|
|
||||||
using (var originalImage = GetImage(inputPath, options.CropWhiteSpace))
|
|
||||||
{
|
|
||||||
if (options.CropWhiteSpace || !originalImageSize.HasValue)
|
|
||||||
{
|
|
||||||
originalImageSize = new ImageSize(originalImage.Width, originalImage.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize);
|
|
||||||
|
|
||||||
var newWidth = Convert.ToInt32(Math.Round(newImageSize.Width));
|
|
||||||
var newHeight = Convert.ToInt32(Math.Round(newImageSize.Height));
|
|
||||||
|
|
||||||
// Graphics.FromImage will throw an exception if the PixelFormat is Indexed, so we need to handle that here
|
|
||||||
// Also, Webp only supports Format32bppArgb and Format32bppRgb
|
|
||||||
var pixelFormat = selectedOutputFormat == ImageFormat.Webp
|
|
||||||
? PixelFormat.Format32bppArgb
|
|
||||||
: PixelFormat.Format32bppPArgb;
|
|
||||||
|
|
||||||
using (var thumbnail = new Bitmap(newWidth, newHeight, pixelFormat))
|
|
||||||
{
|
|
||||||
// Mono throw an exeception if assign 0 to SetResolution
|
|
||||||
if (originalImage.HorizontalResolution > 0 && originalImage.VerticalResolution > 0)
|
|
||||||
{
|
|
||||||
// Preserve the original resolution
|
|
||||||
thumbnail.SetResolution(originalImage.HorizontalResolution, originalImage.VerticalResolution);
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var thumbnailGraph = Graphics.FromImage(thumbnail))
|
|
||||||
{
|
|
||||||
thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality;
|
|
||||||
thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality;
|
|
||||||
thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
||||||
thumbnailGraph.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
||||||
|
|
||||||
// SourceCopy causes the image to be blank in OSX
|
|
||||||
//thumbnailGraph.CompositingMode = !hasPostProcessing ?
|
|
||||||
// CompositingMode.SourceCopy :
|
|
||||||
// CompositingMode.SourceOver;
|
|
||||||
|
|
||||||
SetBackgroundColor(thumbnailGraph, options);
|
|
||||||
|
|
||||||
thumbnailGraph.DrawImage(originalImage, 0, 0, newWidth, newHeight);
|
|
||||||
|
|
||||||
DrawIndicator(thumbnailGraph, newWidth, newHeight, options);
|
|
||||||
|
|
||||||
var outputFormat = GetOutputFormat(originalImage, selectedOutputFormat);
|
|
||||||
|
|
||||||
// Save to the cache location
|
|
||||||
using (var cacheFileStream = _fileSystem.GetFileStream(outputPath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, false))
|
|
||||||
{
|
|
||||||
// Save to the memory stream
|
|
||||||
thumbnail.Save(outputFormat, cacheFileStream, quality);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the color of the background.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="graphics">The graphics.</param>
|
|
||||||
/// <param name="options">The options.</param>
|
|
||||||
private void SetBackgroundColor(Graphics graphics, ImageProcessingOptions options)
|
|
||||||
{
|
|
||||||
var color = options.BackgroundColor;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(color))
|
|
||||||
{
|
|
||||||
Color drawingColor;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
drawingColor = ColorTranslator.FromHtml(color);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
drawingColor = ColorTranslator.FromHtml("#" + color);
|
|
||||||
}
|
|
||||||
|
|
||||||
graphics.Clear(drawingColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Draws the indicator.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="graphics">The graphics.</param>
|
|
||||||
/// <param name="imageWidth">Width of the image.</param>
|
|
||||||
/// <param name="imageHeight">Height of the image.</param>
|
|
||||||
/// <param name="options">The options.</param>
|
|
||||||
private void DrawIndicator(Graphics graphics, int imageWidth, int imageHeight, ImageProcessingOptions options)
|
|
||||||
{
|
|
||||||
if (!options.AddPlayedIndicator && !options.UnplayedCount.HasValue && options.PercentPlayed.Equals(0))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (options.AddPlayedIndicator)
|
|
||||||
{
|
|
||||||
var currentImageSize = new Size(imageWidth, imageHeight);
|
|
||||||
|
|
||||||
new PlayedIndicatorDrawer().DrawPlayedIndicator(graphics, currentImageSize);
|
|
||||||
}
|
|
||||||
else if (options.UnplayedCount.HasValue)
|
|
||||||
{
|
|
||||||
var currentImageSize = new Size(imageWidth, imageHeight);
|
|
||||||
|
|
||||||
new UnplayedCountIndicator().DrawUnplayedCountIndicator(graphics, currentImageSize, options.UnplayedCount.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.PercentPlayed > 0)
|
|
||||||
{
|
|
||||||
var currentImageSize = new Size(imageWidth, imageHeight);
|
|
||||||
|
|
||||||
new PercentPlayedDrawer().Process(graphics, currentImageSize, options.PercentPlayed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.ErrorException("Error drawing indicator overlay", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the output format.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="image">The image.</param>
|
|
||||||
/// <param name="outputFormat">The output format.</param>
|
|
||||||
/// <returns>ImageFormat.</returns>
|
|
||||||
private System.Drawing.Imaging.ImageFormat GetOutputFormat(Image image, ImageFormat outputFormat)
|
|
||||||
{
|
|
||||||
switch (outputFormat)
|
|
||||||
{
|
|
||||||
case ImageFormat.Bmp:
|
|
||||||
return System.Drawing.Imaging.ImageFormat.Bmp;
|
|
||||||
case ImageFormat.Gif:
|
|
||||||
return System.Drawing.Imaging.ImageFormat.Gif;
|
|
||||||
case ImageFormat.Jpg:
|
|
||||||
return System.Drawing.Imaging.ImageFormat.Jpeg;
|
|
||||||
case ImageFormat.Png:
|
|
||||||
return System.Drawing.Imaging.ImageFormat.Png;
|
|
||||||
default:
|
|
||||||
return image.RawFormat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateImageCollage(ImageCollageOptions options)
|
|
||||||
{
|
|
||||||
double ratio = options.Width;
|
|
||||||
ratio /= options.Height;
|
|
||||||
|
|
||||||
if (ratio >= 1.4)
|
|
||||||
{
|
|
||||||
DynamicImageHelpers.CreateThumbCollage(options.InputPaths.ToList(), _fileSystem, options.OutputPath, options.Width, options.Height);
|
|
||||||
}
|
|
||||||
else if (ratio >= .9)
|
|
||||||
{
|
|
||||||
DynamicImageHelpers.CreateSquareCollage(options.InputPaths.ToList(), _fileSystem, options.OutputPath, options.Width, options.Height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DynamicImageHelpers.CreateSquareCollage(options.InputPaths.ToList(), _fileSystem, options.OutputPath, options.Width, options.Width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "GDI"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SupportsImageCollageCreation
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SupportsImageEncoding
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,217 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.Net
|
|
||||||
{
|
|
||||||
public static class ImageExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the image.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="outputFormat">The output format.</param>
|
|
||||||
/// <param name="image">The image.</param>
|
|
||||||
/// <param name="toStream">To stream.</param>
|
|
||||||
/// <param name="quality">The quality.</param>
|
|
||||||
public static void Save(this Image image, ImageFormat outputFormat, Stream toStream, int quality)
|
|
||||||
{
|
|
||||||
// Use special save methods for jpeg and png that will result in a much higher quality image
|
|
||||||
// All other formats use the generic Image.Save
|
|
||||||
if (ImageFormat.Jpeg.Equals(outputFormat))
|
|
||||||
{
|
|
||||||
SaveAsJpeg(image, toStream, quality);
|
|
||||||
}
|
|
||||||
else if (ImageFormat.Png.Equals(outputFormat))
|
|
||||||
{
|
|
||||||
image.Save(toStream, ImageFormat.Png);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
image.Save(toStream, outputFormat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the JPEG.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="image">The image.</param>
|
|
||||||
/// <param name="target">The target.</param>
|
|
||||||
/// <param name="quality">The quality.</param>
|
|
||||||
public static void SaveAsJpeg(this Image image, Stream target, int quality)
|
|
||||||
{
|
|
||||||
using (var encoderParameters = new EncoderParameters(1))
|
|
||||||
{
|
|
||||||
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
|
|
||||||
image.Save(target, GetImageCodecInfo("image/jpeg"), encoderParameters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly ImageCodecInfo[] Encoders = ImageCodecInfo.GetImageEncoders();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the image codec info.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="mimeType">Type of the MIME.</param>
|
|
||||||
/// <returns>ImageCodecInfo.</returns>
|
|
||||||
private static ImageCodecInfo GetImageCodecInfo(string mimeType)
|
|
||||||
{
|
|
||||||
foreach (var encoder in Encoders)
|
|
||||||
{
|
|
||||||
if (string.Equals(encoder.MimeType, mimeType, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return encoder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Encoders.Length == 0 ? null : Encoders[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Crops an image by removing whitespace and transparency from the edges
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bmp">The BMP.</param>
|
|
||||||
/// <returns>Bitmap.</returns>
|
|
||||||
/// <exception cref="System.Exception"></exception>
|
|
||||||
public static Bitmap CropWhitespace(this Bitmap bmp)
|
|
||||||
{
|
|
||||||
var width = bmp.Width;
|
|
||||||
var height = bmp.Height;
|
|
||||||
|
|
||||||
var topmost = 0;
|
|
||||||
for (int row = 0; row < height; ++row)
|
|
||||||
{
|
|
||||||
if (IsAllWhiteRow(bmp, row, width))
|
|
||||||
topmost = row;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bottommost = 0;
|
|
||||||
for (int row = height - 1; row >= 0; --row)
|
|
||||||
{
|
|
||||||
if (IsAllWhiteRow(bmp, row, width))
|
|
||||||
bottommost = row;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int leftmost = 0, rightmost = 0;
|
|
||||||
for (int col = 0; col < width; ++col)
|
|
||||||
{
|
|
||||||
if (IsAllWhiteColumn(bmp, col, height))
|
|
||||||
leftmost = col;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int col = width - 1; col >= 0; --col)
|
|
||||||
{
|
|
||||||
if (IsAllWhiteColumn(bmp, col, height))
|
|
||||||
rightmost = col;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rightmost == 0) rightmost = width; // As reached left
|
|
||||||
if (bottommost == 0) bottommost = height; // As reached top.
|
|
||||||
|
|
||||||
var croppedWidth = rightmost - leftmost;
|
|
||||||
var croppedHeight = bottommost - topmost;
|
|
||||||
|
|
||||||
if (croppedWidth == 0) // No border on left or right
|
|
||||||
{
|
|
||||||
leftmost = 0;
|
|
||||||
croppedWidth = width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (croppedHeight == 0) // No border on top or bottom
|
|
||||||
{
|
|
||||||
topmost = 0;
|
|
||||||
croppedHeight = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Graphics.FromImage will throw an exception if the PixelFormat is Indexed, so we need to handle that here
|
|
||||||
var thumbnail = new Bitmap(croppedWidth, croppedHeight, PixelFormat.Format32bppPArgb);
|
|
||||||
|
|
||||||
// Preserve the original resolution
|
|
||||||
TrySetResolution(thumbnail, bmp.HorizontalResolution, bmp.VerticalResolution);
|
|
||||||
|
|
||||||
using (var thumbnailGraph = Graphics.FromImage(thumbnail))
|
|
||||||
{
|
|
||||||
thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality;
|
|
||||||
thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality;
|
|
||||||
thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
||||||
thumbnailGraph.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
||||||
thumbnailGraph.CompositingMode = CompositingMode.SourceCopy;
|
|
||||||
|
|
||||||
thumbnailGraph.DrawImage(bmp,
|
|
||||||
new RectangleF(0, 0, croppedWidth, croppedHeight),
|
|
||||||
new RectangleF(leftmost, topmost, croppedWidth, croppedHeight),
|
|
||||||
GraphicsUnit.Pixel);
|
|
||||||
}
|
|
||||||
return thumbnail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tries the set resolution.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bmp">The BMP.</param>
|
|
||||||
/// <param name="x">The x.</param>
|
|
||||||
/// <param name="y">The y.</param>
|
|
||||||
private static void TrySetResolution(Bitmap bmp, float x, float y)
|
|
||||||
{
|
|
||||||
if (x > 0 && y > 0)
|
|
||||||
{
|
|
||||||
bmp.SetResolution(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether or not a row of pixels is all whitespace
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bmp">The BMP.</param>
|
|
||||||
/// <param name="row">The row.</param>
|
|
||||||
/// <param name="width">The width.</param>
|
|
||||||
/// <returns><c>true</c> if [is all white row] [the specified BMP]; otherwise, <c>false</c>.</returns>
|
|
||||||
private static bool IsAllWhiteRow(Bitmap bmp, int row, int width)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < width; ++i)
|
|
||||||
{
|
|
||||||
if (!IsWhiteSpace(bmp.GetPixel(i, row)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether or not a column of pixels is all whitespace
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bmp">The BMP.</param>
|
|
||||||
/// <param name="col">The col.</param>
|
|
||||||
/// <param name="height">The height.</param>
|
|
||||||
/// <returns><c>true</c> if [is all white column] [the specified BMP]; otherwise, <c>false</c>.</returns>
|
|
||||||
private static bool IsAllWhiteColumn(Bitmap bmp, int col, int height)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < height; ++i)
|
|
||||||
{
|
|
||||||
if (!IsWhiteSpace(bmp.GetPixel(col, i)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines if a color is whitespace
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="color">The color.</param>
|
|
||||||
/// <returns><c>true</c> if [is white space] [the specified color]; otherwise, <c>false</c>.</returns>
|
|
||||||
private static bool IsWhiteSpace(Color color)
|
|
||||||
{
|
|
||||||
return (color.R == 255 && color.G == 255 && color.B == 255) || color.A == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.Net
|
|
||||||
{
|
|
||||||
internal static class ImageHelpers
|
|
||||||
{
|
|
||||||
internal static List<string> ProjectPaths(List<string> paths, int count)
|
|
||||||
{
|
|
||||||
if (count <= 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException("count");
|
|
||||||
}
|
|
||||||
if (paths.Count == 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException("paths");
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = new List<string>();
|
|
||||||
|
|
||||||
AddToList(list, paths, count);
|
|
||||||
|
|
||||||
return list.Take(count).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddToList(List<string> list, List<string> paths, int count)
|
|
||||||
{
|
|
||||||
while (list.Count < count)
|
|
||||||
{
|
|
||||||
foreach (var path in paths)
|
|
||||||
{
|
|
||||||
list.Add(path);
|
|
||||||
|
|
||||||
if (list.Count >= count)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.Net
|
|
||||||
{
|
|
||||||
public class PercentPlayedDrawer
|
|
||||||
{
|
|
||||||
private const int IndicatorHeight = 8;
|
|
||||||
|
|
||||||
public void Process(Graphics graphics, Size imageSize, double percent)
|
|
||||||
{
|
|
||||||
var y = imageSize.Height - IndicatorHeight;
|
|
||||||
|
|
||||||
using (var backdroundBrush = new SolidBrush(Color.FromArgb(225, 0, 0, 0)))
|
|
||||||
{
|
|
||||||
const int innerX = 0;
|
|
||||||
var innerY = y;
|
|
||||||
var innerWidth = imageSize.Width;
|
|
||||||
var innerHeight = imageSize.Height;
|
|
||||||
|
|
||||||
graphics.FillRectangle(backdroundBrush, innerX, innerY, innerWidth, innerHeight);
|
|
||||||
|
|
||||||
using (var foregroundBrush = new SolidBrush(Color.FromArgb(82, 181, 75)))
|
|
||||||
{
|
|
||||||
double foregroundWidth = innerWidth;
|
|
||||||
foregroundWidth *= percent;
|
|
||||||
foregroundWidth /= 100;
|
|
||||||
|
|
||||||
graphics.FillRectangle(foregroundBrush, innerX, innerY, Convert.ToInt32(Math.Round(foregroundWidth)), innerHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.Net
|
|
||||||
{
|
|
||||||
public class PlayedIndicatorDrawer
|
|
||||||
{
|
|
||||||
private const int IndicatorHeight = 40;
|
|
||||||
public const int IndicatorWidth = 40;
|
|
||||||
private const int FontSize = 40;
|
|
||||||
private const int OffsetFromTopRightCorner = 10;
|
|
||||||
|
|
||||||
public void DrawPlayedIndicator(Graphics graphics, Size imageSize)
|
|
||||||
{
|
|
||||||
var x = imageSize.Width - IndicatorWidth - OffsetFromTopRightCorner;
|
|
||||||
|
|
||||||
using (var backdroundBrush = new SolidBrush(Color.FromArgb(225, 82, 181, 75)))
|
|
||||||
{
|
|
||||||
graphics.FillEllipse(backdroundBrush, x, OffsetFromTopRightCorner, IndicatorWidth, IndicatorHeight);
|
|
||||||
|
|
||||||
x = imageSize.Width - 45 - OffsetFromTopRightCorner;
|
|
||||||
|
|
||||||
using (var font = new Font("Webdings", FontSize, FontStyle.Regular, GraphicsUnit.Pixel))
|
|
||||||
{
|
|
||||||
using (var fontBrush = new SolidBrush(Color.White))
|
|
||||||
{
|
|
||||||
graphics.DrawString("a", font, fontBrush, x, OffsetFromTopRightCorner - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("Emby.Drawing.Net")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("")]
|
|
||||||
[assembly: AssemblyProduct("Emby.Drawing.Net")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("c97a239e-a96c-4d64-a844-ccf8cc30aecb")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
|
||||||
// by using the '*' as shown below:
|
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
|
||||||
[assembly: AssemblyVersion("1.0.0.0")]
|
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
|
@ -1,50 +0,0 @@
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace Emby.Drawing.Net
|
|
||||||
{
|
|
||||||
public class UnplayedCountIndicator
|
|
||||||
{
|
|
||||||
private const int IndicatorHeight = 41;
|
|
||||||
public const int IndicatorWidth = 41;
|
|
||||||
private const int OffsetFromTopRightCorner = 10;
|
|
||||||
|
|
||||||
public void DrawUnplayedCountIndicator(Graphics graphics, Size imageSize, int count)
|
|
||||||
{
|
|
||||||
var x = imageSize.Width - IndicatorWidth - OffsetFromTopRightCorner;
|
|
||||||
|
|
||||||
using (var backdroundBrush = new SolidBrush(Color.FromArgb(225, 82, 181, 75)))
|
|
||||||
{
|
|
||||||
graphics.FillEllipse(backdroundBrush, x, OffsetFromTopRightCorner, IndicatorWidth, IndicatorHeight);
|
|
||||||
|
|
||||||
var text = count.ToString();
|
|
||||||
|
|
||||||
x = imageSize.Width - IndicatorWidth - OffsetFromTopRightCorner;
|
|
||||||
var y = OffsetFromTopRightCorner + 6;
|
|
||||||
var fontSize = 24;
|
|
||||||
|
|
||||||
if (text.Length == 1)
|
|
||||||
{
|
|
||||||
x += 10;
|
|
||||||
}
|
|
||||||
else if (text.Length == 2)
|
|
||||||
{
|
|
||||||
x += 3;
|
|
||||||
}
|
|
||||||
else if (text.Length == 3)
|
|
||||||
{
|
|
||||||
x += 1;
|
|
||||||
y += 1;
|
|
||||||
fontSize = 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var font = new Font("Sans-Serif", fontSize, FontStyle.Regular, GraphicsUnit.Pixel))
|
|
||||||
{
|
|
||||||
using (var fontBrush = new SolidBrush(Color.White))
|
|
||||||
{
|
|
||||||
graphics.DrawString(text, font, fontBrush, x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 68 B |
|
@ -3,7 +3,7 @@ using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -81,7 +81,7 @@ namespace Emby.Drawing.Skia
|
||||||
// test an operation that requires the native library
|
// test an operation that requires the native library
|
||||||
SKPMColor.PreMultiply(SKColors.Black);
|
SKPMColor.PreMultiply(SKColors.Black);
|
||||||
|
|
||||||
_logger.Info("SkiaSharp version: " + GetVersion());
|
_logger.LogInformation("SkiaSharp version: " + GetVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetVersion()
|
public static string GetVersion()
|
||||||
|
@ -530,7 +530,7 @@ namespace Emby.Drawing.Skia
|
||||||
throw new ArgumentOutOfRangeException(string.Format("Skia unable to read image {0}", inputPath));
|
throw new ArgumentOutOfRangeException(string.Format("Skia unable to read image {0}", inputPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
//_logger.Info("Color type {0}", bitmap.Info.ColorType);
|
//_logger.LogInformation("Color type {0}", bitmap.Info.ColorType);
|
||||||
|
|
||||||
var originalImageSize = new ImageSize(bitmap.Width, bitmap.Height);
|
var originalImageSize = new ImageSize(bitmap.Width, bitmap.Height);
|
||||||
|
|
||||||
|
@ -548,9 +548,7 @@ namespace Emby.Drawing.Skia
|
||||||
using (var resizedBitmap = new SKBitmap(width, height))//, bitmap.ColorType, bitmap.AlphaType))
|
using (var resizedBitmap = new SKBitmap(width, height))//, bitmap.ColorType, bitmap.AlphaType))
|
||||||
{
|
{
|
||||||
// scale image
|
// scale image
|
||||||
var resizeMethod = SKBitmapResizeMethod.Lanczos3;
|
bitmap.ScalePixels(resizedBitmap, SKFilterQuality.High);
|
||||||
|
|
||||||
bitmap.Resize(resizedBitmap, resizeMethod);
|
|
||||||
|
|
||||||
// If all we're doing is resizing then we can stop now
|
// If all we're doing is resizing then we can stop now
|
||||||
if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator)
|
if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator)
|
||||||
|
@ -558,10 +556,13 @@ namespace Emby.Drawing.Skia
|
||||||
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(outputPath));
|
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(outputPath));
|
||||||
using (var outputStream = new SKFileWStream(outputPath))
|
using (var outputStream = new SKFileWStream(outputPath))
|
||||||
{
|
{
|
||||||
resizedBitmap.Encode(outputStream, skiaOutputFormat, quality);
|
using (var pixmap = new SKPixmap(new SKImageInfo(width, height), resizedBitmap.GetPixels()))
|
||||||
|
{
|
||||||
|
pixmap.Encode(outputStream, skiaOutputFormat, quality);
|
||||||
return outputPath;
|
return outputPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create bitmap to use for canvas drawing used to draw into bitmap
|
// create bitmap to use for canvas drawing used to draw into bitmap
|
||||||
using (var saveBitmap = new SKBitmap(width, height))//, bitmap.ColorType, bitmap.AlphaType))
|
using (var saveBitmap = new SKBitmap(width, height))//, bitmap.ColorType, bitmap.AlphaType))
|
||||||
|
@ -593,8 +594,7 @@ namespace Emby.Drawing.Skia
|
||||||
// If foreground layer present then draw
|
// If foreground layer present then draw
|
||||||
if (hasForegroundColor)
|
if (hasForegroundColor)
|
||||||
{
|
{
|
||||||
Double opacity;
|
if (!Double.TryParse(options.ForegroundLayer, out double opacity))
|
||||||
if (!Double.TryParse(options.ForegroundLayer, out opacity))
|
|
||||||
{
|
{
|
||||||
opacity = .4;
|
opacity = .4;
|
||||||
}
|
}
|
||||||
|
@ -610,7 +610,10 @@ namespace Emby.Drawing.Skia
|
||||||
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(outputPath));
|
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(outputPath));
|
||||||
using (var outputStream = new SKFileWStream(outputPath))
|
using (var outputStream = new SKFileWStream(outputPath))
|
||||||
{
|
{
|
||||||
saveBitmap.Encode(outputStream, skiaOutputFormat, quality);
|
using (var pixmap = new SKPixmap(new SKImageInfo(width, height), saveBitmap.GetPixels()))
|
||||||
|
{
|
||||||
|
pixmap.Encode(outputStream, skiaOutputFormat, quality);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -660,7 +663,7 @@ namespace Emby.Drawing.Skia
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error drawing indicator overlay", ex);
|
_logger.LogError(ex, "Error drawing indicator overlay");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,10 @@ namespace Emby.Drawing.Skia
|
||||||
{
|
{
|
||||||
using (var outputStream = new SKFileWStream(outputPath))
|
using (var outputStream = new SKFileWStream(outputPath))
|
||||||
{
|
{
|
||||||
bitmap.Encode(outputStream, GetEncodedFormat(outputPath), 90);
|
using (var pixmap = new SKPixmap(new SKImageInfo(width, height), bitmap.GetPixels()))
|
||||||
|
{
|
||||||
|
pixmap.Encode(outputStream, GetEncodedFormat(outputPath), 90);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +63,10 @@ namespace Emby.Drawing.Skia
|
||||||
{
|
{
|
||||||
using (var outputStream = new SKFileWStream(outputPath))
|
using (var outputStream = new SKFileWStream(outputPath))
|
||||||
{
|
{
|
||||||
bitmap.Encode(outputStream, GetEncodedFormat(outputPath), 90);
|
using (var pixmap = new SKPixmap(new SKImageInfo(width, height), bitmap.GetPixels()))
|
||||||
|
{
|
||||||
|
pixmap.Encode(outputStream, GetEncodedFormat(outputPath), 90);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,9 +89,8 @@ namespace Emby.Drawing.Skia
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
int newIndex;
|
|
||||||
|
|
||||||
using (var currentBitmap = GetNextValidImage(paths, imageIndex, out newIndex))
|
using (var currentBitmap = GetNextValidImage(paths, imageIndex, out int newIndex))
|
||||||
{
|
{
|
||||||
imageIndex = newIndex;
|
imageIndex = newIndex;
|
||||||
|
|
||||||
|
@ -98,7 +103,7 @@ namespace Emby.Drawing.Skia
|
||||||
int iWidth = (int)Math.Abs(iHeight * currentBitmap.Width / currentBitmap.Height);
|
int iWidth = (int)Math.Abs(iHeight * currentBitmap.Width / currentBitmap.Height);
|
||||||
using (var resizeBitmap = new SKBitmap(iWidth, iHeight, currentBitmap.ColorType, currentBitmap.AlphaType))
|
using (var resizeBitmap = new SKBitmap(iWidth, iHeight, currentBitmap.ColorType, currentBitmap.AlphaType))
|
||||||
{
|
{
|
||||||
currentBitmap.Resize(resizeBitmap, SKBitmapResizeMethod.Lanczos3);
|
currentBitmap.ScalePixels(resizeBitmap, SKFilterQuality.High);
|
||||||
// crop image
|
// crop image
|
||||||
int ix = (int)Math.Abs((iWidth - iSlice) / 2);
|
int ix = (int)Math.Abs((iWidth - iSlice) / 2);
|
||||||
using (var image = SKImage.FromBitmap(resizeBitmap))
|
using (var image = SKImage.FromBitmap(resizeBitmap))
|
||||||
|
@ -116,7 +121,7 @@ namespace Emby.Drawing.Skia
|
||||||
using (var reflectionBitmap = new SKBitmap(croppedBitmap.Width, croppedBitmap.Height / 2, croppedBitmap.ColorType, croppedBitmap.AlphaType))
|
using (var reflectionBitmap = new SKBitmap(croppedBitmap.Width, croppedBitmap.Height / 2, croppedBitmap.ColorType, croppedBitmap.AlphaType))
|
||||||
{
|
{
|
||||||
// resize to half height
|
// resize to half height
|
||||||
croppedBitmap.Resize(reflectionBitmap, SKBitmapResizeMethod.Lanczos3);
|
currentBitmap.ScalePixels(reflectionBitmap, SKFilterQuality.High);
|
||||||
|
|
||||||
using (var flippedBitmap = new SKBitmap(reflectionBitmap.Width, reflectionBitmap.Height, reflectionBitmap.ColorType, reflectionBitmap.AlphaType))
|
using (var flippedBitmap = new SKBitmap(reflectionBitmap.Width, reflectionBitmap.Height, reflectionBitmap.ColorType, reflectionBitmap.AlphaType))
|
||||||
using (var flippedCanvas = new SKCanvas(flippedBitmap))
|
using (var flippedCanvas = new SKCanvas(flippedBitmap))
|
||||||
|
@ -164,8 +169,7 @@ namespace Emby.Drawing.Skia
|
||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SKEncodedOrigin origin;
|
bitmap = SkiaEncoder.Decode(paths[currentIndex], false, _fileSystem, null, out SKEncodedOrigin origin);
|
||||||
bitmap = SkiaEncoder.Decode(paths[currentIndex], false, _fileSystem, null, out origin);
|
|
||||||
|
|
||||||
imagesTested[currentIndex] = 0;
|
imagesTested[currentIndex] = 0;
|
||||||
|
|
||||||
|
@ -194,9 +198,8 @@ namespace Emby.Drawing.Skia
|
||||||
{
|
{
|
||||||
for (var y = 0; y < 2; y++)
|
for (var y = 0; y < 2; y++)
|
||||||
{
|
{
|
||||||
int newIndex;
|
|
||||||
|
|
||||||
using (var currentBitmap = GetNextValidImage(paths, imageIndex, out newIndex))
|
using (var currentBitmap = GetNextValidImage(paths, imageIndex, out int newIndex))
|
||||||
{
|
{
|
||||||
imageIndex = newIndex;
|
imageIndex = newIndex;
|
||||||
|
|
||||||
|
@ -208,7 +211,7 @@ namespace Emby.Drawing.Skia
|
||||||
using (var resizedBitmap = new SKBitmap(cellWidth, cellHeight, currentBitmap.ColorType, currentBitmap.AlphaType))
|
using (var resizedBitmap = new SKBitmap(cellWidth, cellHeight, currentBitmap.ColorType, currentBitmap.AlphaType))
|
||||||
{
|
{
|
||||||
// scale image
|
// scale image
|
||||||
currentBitmap.Resize(resizedBitmap, SKBitmapResizeMethod.Lanczos3);
|
currentBitmap.ScalePixels(resizedBitmap, SKFilterQuality.High);
|
||||||
|
|
||||||
// draw this image into the strip at the next position
|
// draw this image into the strip at the next position
|
||||||
var xPos = x * cellWidth;
|
var xPos = x * cellWidth;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -5,7 +5,7 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
@ -261,7 +261,7 @@ namespace Emby.Drawing
|
||||||
//if (originalImageSize.HasValue && options.HasDefaultOptions(originalImagePath, originalImageSize.Value) && !autoOrient)
|
//if (originalImageSize.HasValue && options.HasDefaultOptions(originalImagePath, originalImageSize.Value) && !autoOrient)
|
||||||
//{
|
//{
|
||||||
// // Just spit out the original file if all the options are default
|
// // Just spit out the original file if all the options are default
|
||||||
// _logger.Info("Returning original image {0}", originalImagePath);
|
// _logger.LogInformation("Returning original image {0}", originalImagePath);
|
||||||
// return new ValueTuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
|
// return new ValueTuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ namespace Emby.Drawing
|
||||||
{
|
{
|
||||||
// Decoder failed to decode it
|
// Decoder failed to decode it
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
_logger.ErrorException("Error encoding image", ex);
|
_logger.LogError(ex, "Error encoding image");
|
||||||
#endif
|
#endif
|
||||||
// Just spit out the original file if all the options are default
|
// Just spit out the original file if all the options are default
|
||||||
return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
|
return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
|
||||||
|
@ -310,7 +310,7 @@ namespace Emby.Drawing
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// If it fails for whatever reason, return the original image
|
// If it fails for whatever reason, return the original image
|
||||||
_logger.ErrorException("Error encoding image", ex);
|
_logger.LogError(ex, "Error encoding image");
|
||||||
|
|
||||||
// Just spit out the original file if all the options are default
|
// Just spit out the original file if all the options are default
|
||||||
return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
|
return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
|
||||||
|
@ -464,7 +464,7 @@ namespace Emby.Drawing
|
||||||
}
|
}
|
||||||
|
|
||||||
var path = info.Path;
|
var path = info.Path;
|
||||||
_logger.Info("Getting image size for item {0} {1}", item.GetType().Name, path);
|
_logger.LogInformation("Getting image size for item {0} {1}", item.GetType().Name, path);
|
||||||
|
|
||||||
var size = GetImageSize(path, allowSlowMethods);
|
var size = GetImageSize(path, allowSlowMethods);
|
||||||
|
|
||||||
|
@ -603,7 +603,7 @@ namespace Emby.Drawing
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Image conversion failed for {0}", ex, originalImagePath);
|
_logger.LogError(ex, "Image conversion failed for {originalImagePath}", originalImagePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,21 +646,21 @@ namespace Emby.Drawing
|
||||||
var cacheGuid = GetImageCacheTag(item, image, enhancers);
|
var cacheGuid = GetImageCacheTag(item, image, enhancers);
|
||||||
|
|
||||||
// Enhance if we have enhancers
|
// Enhance if we have enhancers
|
||||||
var ehnancedImageInfo = await GetEnhancedImageInternal(originalImagePath, item, imageType, imageIndex, enhancers, cacheGuid, cancellationToken).ConfigureAwait(false);
|
var enhancedImageInfo = await GetEnhancedImageInternal(originalImagePath, item, imageType, imageIndex, enhancers, cacheGuid, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var ehnancedImagePath = ehnancedImageInfo.Item1;
|
var enhancedImagePath = enhancedImageInfo.Item1;
|
||||||
|
|
||||||
// If the path changed update dateModified
|
// If the path changed update dateModified
|
||||||
if (!string.Equals(ehnancedImagePath, originalImagePath, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(enhancedImagePath, originalImagePath, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var treatmentRequiresTransparency = ehnancedImageInfo.Item2;
|
var treatmentRequiresTransparency = enhancedImageInfo.Item2;
|
||||||
|
|
||||||
return new ValueTuple<string, DateTime, bool>(ehnancedImagePath, _fileSystem.GetLastWriteTimeUtc(ehnancedImagePath), treatmentRequiresTransparency);
|
return new ValueTuple<string, DateTime, bool>(enhancedImagePath, _fileSystem.GetLastWriteTimeUtc(enhancedImagePath), treatmentRequiresTransparency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error enhancing image", ex);
|
_logger.LogError(ex, "Error enhancing image");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ValueTuple<string, DateTime, bool>(originalImagePath, dateModified, inputImageSupportsTransparency);
|
return new ValueTuple<string, DateTime, bool>(originalImagePath, dateModified, inputImageSupportsTransparency);
|
||||||
|
@ -827,11 +827,11 @@ namespace Emby.Drawing
|
||||||
|
|
||||||
public void CreateImageCollage(ImageCollageOptions options)
|
public void CreateImageCollage(ImageCollageOptions options)
|
||||||
{
|
{
|
||||||
_logger.Info("Creating image collage and saving to {0}", options.OutputPath);
|
_logger.LogInformation("Creating image collage and saving to {0}", options.OutputPath);
|
||||||
|
|
||||||
_imageEncoder.CreateImageCollage(options);
|
_imageEncoder.CreateImageCollage(options);
|
||||||
|
|
||||||
_logger.Info("Completed creation of image collage and saved to {0}", options.OutputPath);
|
_logger.LogInformation("Completed creation of image collage and saved to {0}", options.OutputPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IImageEnhancer[] GetSupportedEnhancers(BaseItem item, ImageType imageType)
|
public IImageEnhancer[] GetSupportedEnhancers(BaseItem item, ImageType imageType)
|
||||||
|
@ -853,7 +853,7 @@ namespace Emby.Drawing
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error in image enhancer: {0}", ex, i.GetType().Name);
|
_logger.LogError(ex, "Error in image enhancer: {0}", i.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Diagnostics;
|
using MediaBrowser.Model.Diagnostics;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.System;
|
using MediaBrowser.Model.System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ namespace IsoMounter
|
||||||
private readonly IEnvironmentInfo EnvironmentInfo;
|
private readonly IEnvironmentInfo EnvironmentInfo;
|
||||||
private readonly bool ExecutablesAvailable;
|
private readonly bool ExecutablesAvailable;
|
||||||
private readonly IFileSystem FileSystem;
|
private readonly IFileSystem FileSystem;
|
||||||
private readonly ILogger Logger;
|
private readonly ILogger _logger;
|
||||||
private readonly string MountCommand;
|
private readonly string MountCommand;
|
||||||
private readonly string MountPointRoot;
|
private readonly string MountPointRoot;
|
||||||
private readonly IProcessFactory ProcessFactory;
|
private readonly IProcessFactory ProcessFactory;
|
||||||
|
@ -36,24 +36,24 @@ namespace IsoMounter
|
||||||
|
|
||||||
EnvironmentInfo = environment;
|
EnvironmentInfo = environment;
|
||||||
FileSystem = fileSystem;
|
FileSystem = fileSystem;
|
||||||
Logger = logger;
|
_logger = logger;
|
||||||
ProcessFactory = processFactory;
|
ProcessFactory = processFactory;
|
||||||
|
|
||||||
MountPointRoot = FileSystem.DirectorySeparatorChar + "tmp" + FileSystem.DirectorySeparatorChar + "Emby";
|
MountPointRoot = FileSystem.DirectorySeparatorChar + "tmp" + FileSystem.DirectorySeparatorChar + "Emby";
|
||||||
|
|
||||||
Logger.Debug(
|
_logger.LogDebug(
|
||||||
"[{0}] System PATH is currently set to [{1}].",
|
"[{0}] System PATH is currently set to [{1}].",
|
||||||
Name,
|
Name,
|
||||||
EnvironmentInfo.GetEnvironmentVariable("PATH") ?? ""
|
EnvironmentInfo.GetEnvironmentVariable("PATH") ?? ""
|
||||||
);
|
);
|
||||||
|
|
||||||
Logger.Debug(
|
_logger.LogDebug(
|
||||||
"[{0}] System path separator is [{1}].",
|
"[{0}] System path separator is [{1}].",
|
||||||
Name,
|
Name,
|
||||||
EnvironmentInfo.PathSeparator
|
EnvironmentInfo.PathSeparator
|
||||||
);
|
);
|
||||||
|
|
||||||
Logger.Debug(
|
_logger.LogDebug(
|
||||||
"[{0}] Mount point root is [{1}].",
|
"[{0}] Mount point root is [{1}].",
|
||||||
Name,
|
Name,
|
||||||
MountPointRoot
|
MountPointRoot
|
||||||
|
@ -65,7 +65,7 @@ namespace IsoMounter
|
||||||
|
|
||||||
SudoCommand = GetFullPathForExecutable("sudo");
|
SudoCommand = GetFullPathForExecutable("sudo");
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] Using version of [sudo] located at [{1}].",
|
"[{0}] Using version of [sudo] located at [{1}].",
|
||||||
Name,
|
Name,
|
||||||
SudoCommand
|
SudoCommand
|
||||||
|
@ -73,7 +73,7 @@ namespace IsoMounter
|
||||||
|
|
||||||
MountCommand = GetFullPathForExecutable("mount");
|
MountCommand = GetFullPathForExecutable("mount");
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] Using version of [mount] located at [{1}].",
|
"[{0}] Using version of [mount] located at [{1}].",
|
||||||
Name,
|
Name,
|
||||||
MountCommand
|
MountCommand
|
||||||
|
@ -81,7 +81,7 @@ namespace IsoMounter
|
||||||
|
|
||||||
UmountCommand = GetFullPathForExecutable("umount");
|
UmountCommand = GetFullPathForExecutable("umount");
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] Using version of [umount] located at [{1}].",
|
"[{0}] Using version of [umount] located at [{1}].",
|
||||||
Name,
|
Name,
|
||||||
UmountCommand
|
UmountCommand
|
||||||
|
@ -119,7 +119,7 @@ namespace IsoMounter
|
||||||
{
|
{
|
||||||
|
|
||||||
if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Linux) {
|
if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Linux) {
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] Checking we can attempt to mount [{1}], Extension = [{2}], Operating System = [{3}], Executables Available = [{4}].",
|
"[{0}] Checking we can attempt to mount [{1}], Extension = [{2}], Operating System = [{3}], Executables Available = [{4}].",
|
||||||
Name,
|
Name,
|
||||||
path,
|
path,
|
||||||
|
@ -182,7 +182,7 @@ namespace IsoMounter
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] Disposing [{1}].",
|
"[{0}] Disposing [{1}].",
|
||||||
Name,
|
Name,
|
||||||
disposing.ToString()
|
disposing.ToString()
|
||||||
|
@ -230,7 +230,7 @@ namespace IsoMounter
|
||||||
|
|
||||||
var uid = getuid();
|
var uid = getuid();
|
||||||
|
|
||||||
Logger.Debug(
|
_logger.LogDebug(
|
||||||
"[{0}] Our current UID is [{1}], GetUserId() returned [{2}].",
|
"[{0}] Our current UID is [{1}], GetUserId() returned [{2}].",
|
||||||
Name,
|
Name,
|
||||||
uid.ToString(),
|
uid.ToString(),
|
||||||
|
@ -260,35 +260,29 @@ namespace IsoMounter
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
process.Start();
|
process.Start();
|
||||||
|
|
||||||
//StreamReader outputReader = process.StandardOutput.;
|
//StreamReader outputReader = process.StandardOutput.;
|
||||||
//StreamReader errorReader = process.StandardError;
|
//StreamReader errorReader = process.StandardError;
|
||||||
|
|
||||||
Logger.Debug(
|
_logger.LogDebug(
|
||||||
"[{0}] Standard output from process is [{1}].",
|
"[{Name}] Standard output from process is [{Error}].",
|
||||||
Name,
|
Name,
|
||||||
process.StandardOutput.ReadToEnd()
|
process.StandardOutput.ReadToEnd()
|
||||||
);
|
);
|
||||||
|
|
||||||
Logger.Debug(
|
_logger.LogDebug(
|
||||||
"[{0}] Standard error from process is [{1}].",
|
"[{Name}] Standard error from process is [{Error}].",
|
||||||
Name,
|
Name,
|
||||||
process.StandardError.ReadToEnd()
|
process.StandardError.ReadToEnd()
|
||||||
);
|
);
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
catch (Exception ex)
|
||||||
|
{
|
||||||
processFailed = true;
|
processFailed = true;
|
||||||
|
_logger.LogDebug(ex, "[{Name}] Unhandled exception executing command.", Name);
|
||||||
Logger.Debug(
|
|
||||||
"[{0}] Unhandled exception executing command, exception is [{1}].",
|
|
||||||
Name,
|
|
||||||
ex.Message
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!processFailed && process.ExitCode == 0) {
|
if (!processFailed && process.ExitCode == 0) {
|
||||||
|
@ -308,14 +302,14 @@ namespace IsoMounter
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(isoPath)) {
|
if (!string.IsNullOrEmpty(isoPath)) {
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] Attempting to mount [{1}].",
|
"[{Name}] Attempting to mount [{Path}].",
|
||||||
Name,
|
Name,
|
||||||
isoPath
|
isoPath
|
||||||
);
|
);
|
||||||
|
|
||||||
Logger.Debug(
|
_logger.LogDebug(
|
||||||
"[{0}] ISO will be mounted at [{1}].",
|
"[{Name}] ISO will be mounted at [{Path}].",
|
||||||
Name,
|
Name,
|
||||||
mountPoint
|
mountPoint
|
||||||
);
|
);
|
||||||
|
@ -326,11 +320,16 @@ namespace IsoMounter
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
FileSystem.CreateDirectory(mountPoint);
|
FileSystem.CreateDirectory(mountPoint);
|
||||||
} catch (UnauthorizedAccessException) {
|
}
|
||||||
|
catch (UnauthorizedAccessException)
|
||||||
|
{
|
||||||
throw new IOException("Unable to create mount point(Permission denied) for " + isoPath);
|
throw new IOException("Unable to create mount point(Permission denied) for " + isoPath);
|
||||||
} catch (Exception) {
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
throw new IOException("Unable to create mount point for " + isoPath);
|
throw new IOException("Unable to create mount point for " + isoPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +341,7 @@ namespace IsoMounter
|
||||||
cmdArguments = string.Format("\"{0}\" \"{1}\" \"{2}\"", MountCommand, isoPath, mountPoint);
|
cmdArguments = string.Format("\"{0}\" \"{1}\" \"{2}\"", MountCommand, isoPath, mountPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug(
|
_logger.LogDebug(
|
||||||
"[{0}] Mount command [{1}], mount arguments [{2}].",
|
"[{0}] Mount command [{1}], mount arguments [{2}].",
|
||||||
Name,
|
Name,
|
||||||
cmdFilename,
|
cmdFilename,
|
||||||
|
@ -351,7 +350,7 @@ namespace IsoMounter
|
||||||
|
|
||||||
if (ExecuteCommand(cmdFilename, cmdArguments)) {
|
if (ExecuteCommand(cmdFilename, cmdArguments)) {
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] ISO mount completed successfully.",
|
"[{0}] ISO mount completed successfully.",
|
||||||
Name
|
Name
|
||||||
);
|
);
|
||||||
|
@ -360,23 +359,18 @@ namespace IsoMounter
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] ISO mount completed with errors.",
|
"[{0}] ISO mount completed with errors.",
|
||||||
Name
|
Name
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
FileSystem.DeleteDirectory(mountPoint, false);
|
FileSystem.DeleteDirectory(mountPoint, false);
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Logger.Info(
|
_logger.LogInformation(ex, "[{Name}] Unhandled exception removing mount point.", Name);
|
||||||
"[{0}] Unhandled exception removing mount point, exception is [{1}].",
|
|
||||||
Name,
|
|
||||||
ex.Message
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mountedISO = null;
|
mountedISO = null;
|
||||||
|
@ -395,7 +389,7 @@ namespace IsoMounter
|
||||||
|
|
||||||
if (mount != null) {
|
if (mount != null) {
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] Attempting to unmount ISO [{1}] mounted on [{2}].",
|
"[{0}] Attempting to unmount ISO [{1}] mounted on [{2}].",
|
||||||
Name,
|
Name,
|
||||||
mount.IsoPath,
|
mount.IsoPath,
|
||||||
|
@ -416,7 +410,7 @@ namespace IsoMounter
|
||||||
cmdArguments = string.Format("\"{0}\" \"{1}\"", UmountCommand, mount.MountedPath);
|
cmdArguments = string.Format("\"{0}\" \"{1}\"", UmountCommand, mount.MountedPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug(
|
_logger.LogDebug(
|
||||||
"[{0}] Umount command [{1}], umount arguments [{2}].",
|
"[{0}] Umount command [{1}], umount arguments [{2}].",
|
||||||
Name,
|
Name,
|
||||||
cmdFilename,
|
cmdFilename,
|
||||||
|
@ -425,34 +419,28 @@ namespace IsoMounter
|
||||||
|
|
||||||
if (ExecuteCommand(cmdFilename, cmdArguments)) {
|
if (ExecuteCommand(cmdFilename, cmdArguments)) {
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] ISO unmount completed successfully.",
|
"[{0}] ISO unmount completed successfully.",
|
||||||
Name
|
Name
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Logger.Info(
|
_logger.LogInformation(
|
||||||
"[{0}] ISO unmount completed with errors.",
|
"[{0}] ISO unmount completed with errors.",
|
||||||
Name
|
Name
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
FileSystem.DeleteDirectory(mount.MountedPath, false);
|
FileSystem.DeleteDirectory(mount.MountedPath, false);
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
|
|
||||||
Logger.Info(
|
|
||||||
"[{0}] Unhandled exception removing mount point, exception is [{1}].",
|
|
||||||
Name,
|
|
||||||
ex.Message
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogInformation(ex, "[{Name}] Unhandled exception removing mount point.", Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -79,4 +79,3 @@ namespace IsoMounter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Notifications;
|
using MediaBrowser.Controller.Notifications;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Notifications;
|
using MediaBrowser.Model.Notifications;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -25,11 +25,11 @@ namespace Emby.Notifications
|
||||||
private INotificationService[] _services;
|
private INotificationService[] _services;
|
||||||
private INotificationTypeFactory[] _typeFactories;
|
private INotificationTypeFactory[] _typeFactories;
|
||||||
|
|
||||||
public NotificationManager(ILogManager logManager, IUserManager userManager, IServerConfigurationManager config)
|
public NotificationManager(ILoggerFactory loggerFactory, IUserManager userManager, IServerConfigurationManager config)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_config = config;
|
_config = config;
|
||||||
_logger = logManager.GetLogger(GetType().Name);
|
_logger = loggerFactory.CreateLogger(GetType().Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NotificationOptions GetConfiguration()
|
private NotificationOptions GetConfiguration()
|
||||||
|
@ -126,7 +126,7 @@ namespace Emby.Notifications
|
||||||
User = user
|
User = user
|
||||||
};
|
};
|
||||||
|
|
||||||
_logger.Debug("Sending notification via {0} to user {1}", service.Name, user.Name);
|
_logger.LogDebug("Sending notification via {0} to user {1}", service.Name, user.Name);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -134,7 +134,7 @@ namespace Emby.Notifications
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error sending notification to {0}", ex, service.Name);
|
_logger.LogError(ex, "Error sending notification to {0}", service.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ namespace Emby.Notifications
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error in IsEnabledForUser", ex);
|
_logger.LogError(ex, "Error in IsEnabledForUser");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ namespace Emby.Notifications
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error in GetNotificationTypes", ex);
|
_logger.LogError(ex, "Error in GetNotificationTypes");
|
||||||
return new List<NotificationTypeInfo>();
|
return new List<NotificationTypeInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Notifications;
|
using MediaBrowser.Controller.Notifications;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Notifications;
|
using MediaBrowser.Model.Notifications;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using System;
|
using System;
|
||||||
|
@ -137,7 +137,7 @@ namespace Emby.Notifications
|
||||||
|
|
||||||
var notification = new NotificationRequest
|
var notification = new NotificationRequest
|
||||||
{
|
{
|
||||||
Description = "Please see emby.media for details.",
|
Description = "Please see jellyfin.media for details.",
|
||||||
NotificationType = type,
|
NotificationType = type,
|
||||||
Name = _localization.GetLocalizedString("NewVersionIsAvailable")
|
Name = _localization.GetLocalizedString("NewVersionIsAvailable")
|
||||||
};
|
};
|
||||||
|
@ -273,7 +273,7 @@ namespace Emby.Notifications
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error sending notification", ex);
|
_logger.LogError(ex, "Error sending notification");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using TagLib;
|
using TagLib;
|
||||||
using TagLib.IFD;
|
using TagLib.IFD;
|
||||||
using TagLib.IFD.Entries;
|
using TagLib.IFD.Entries;
|
||||||
|
@ -170,9 +170,9 @@ namespace Emby.Photos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Image Provider - Error reading image tag for {0}", e, item.Path);
|
_logger.LogError(ex, "Image Provider - Error reading image tag for {0}", item.Path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Controller.Subtitles;
|
using MediaBrowser.Controller.Subtitles;
|
||||||
using MediaBrowser.Model.Activity;
|
using MediaBrowser.Model.Activity;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using MediaBrowser.Model.Updates;
|
using MediaBrowser.Model.Updates;
|
||||||
using System;
|
using System;
|
||||||
|
@ -129,7 +129,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
//_logger.Warn("PlaybackStopped reported with null media info.");
|
//_logger.LogWarning("PlaybackStopped reported with null media info.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
//_logger.Warn("PlaybackStart reported with null media info.");
|
//_logger.LogWarning("PlaybackStart reported with null media info.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
Name = string.Format(_localization.GetLocalizedString("FailedLoginAttemptWithUserName"), e.Argument.Username),
|
Name = string.Format(_localization.GetLocalizedString("FailedLoginAttemptWithUserName"), e.Argument.Username),
|
||||||
Type = "AuthenticationFailed",
|
Type = "AuthenticationFailed",
|
||||||
ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.RemoteEndPoint),
|
ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.RemoteEndPoint),
|
||||||
Severity = LogSeverity.Error
|
Severity = LogLevel.Error
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
Type = NotificationType.TaskFailed.ToString(),
|
Type = NotificationType.TaskFailed.ToString(),
|
||||||
Overview = string.Join(Environment.NewLine, vals.ToArray()),
|
Overview = string.Join(Environment.NewLine, vals.ToArray()),
|
||||||
ShortOverview = runningTime,
|
ShortOverview = runningTime,
|
||||||
Severity = LogSeverity.Error
|
Severity = LogLevel.Error
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
using MediaBrowser.Common.Events;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Library;
|
|
||||||
using MediaBrowser.Model.Activity;
|
using MediaBrowser.Model.Activity;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -30,7 +29,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
|
|
||||||
_repo.Create(entry);
|
_repo.Create(entry);
|
||||||
|
|
||||||
EventHelper.FireEventIfNotNull(EntryCreated, this, new GenericEventArgs<ActivityLogEntry>(entry), _logger);
|
EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
|
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
|
||||||
|
|
|
@ -6,7 +6,7 @@ using System.Linq;
|
||||||
using Emby.Server.Implementations.Data;
|
using Emby.Server.Implementations.Data;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.Activity;
|
using MediaBrowser.Model.Activity;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using SQLitePCL.pretty;
|
using SQLitePCL.pretty;
|
||||||
using MediaBrowser.Model.Extensions;
|
using MediaBrowser.Model.Extensions;
|
||||||
|
@ -34,7 +34,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error loading database file. Will reset and retry.", ex);
|
Logger.LogError(ex, "Error loading database file. Will reset and retry.");
|
||||||
|
|
||||||
FileSystem.DeleteFile(DbFilePath);
|
FileSystem.DeleteFile(DbFilePath);
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error migrating activity log database", ex);
|
Logger.LogError(ex, "Error migrating activity log database");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,6 @@ namespace Emby.Server.Implementations.Activity
|
||||||
}
|
}
|
||||||
|
|
||||||
using (WriteLock.Write())
|
using (WriteLock.Write())
|
||||||
{
|
|
||||||
using (var connection = CreateConnection())
|
using (var connection = CreateConnection())
|
||||||
{
|
{
|
||||||
connection.RunInTransaction(db =>
|
connection.RunInTransaction(db =>
|
||||||
|
@ -118,7 +117,6 @@ namespace Emby.Server.Implementations.Activity
|
||||||
}, TransactionMode);
|
}, TransactionMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(ActivityLogEntry entry)
|
public void Update(ActivityLogEntry entry)
|
||||||
{
|
{
|
||||||
|
@ -128,7 +126,6 @@ namespace Emby.Server.Implementations.Activity
|
||||||
}
|
}
|
||||||
|
|
||||||
using (WriteLock.Write())
|
using (WriteLock.Write())
|
||||||
{
|
|
||||||
using (var connection = CreateConnection())
|
using (var connection = CreateConnection())
|
||||||
{
|
{
|
||||||
connection.RunInTransaction(db =>
|
connection.RunInTransaction(db =>
|
||||||
|
@ -160,12 +157,10 @@ namespace Emby.Server.Implementations.Activity
|
||||||
}, TransactionMode);
|
}, TransactionMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
|
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
|
||||||
{
|
{
|
||||||
using (WriteLock.Read())
|
using (WriteLock.Read())
|
||||||
{
|
|
||||||
using (var connection = CreateConnection(true))
|
using (var connection = CreateConnection(true))
|
||||||
{
|
{
|
||||||
var commandText = BaseActivitySelectText;
|
var commandText = BaseActivitySelectText;
|
||||||
|
@ -255,7 +250,6 @@ namespace Emby.Server.Implementations.Activity
|
||||||
}, ReadTransactionMode);
|
}, ReadTransactionMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private ActivityLogEntry GetEntry(IReadOnlyList<IResultSetValue> reader)
|
private ActivityLogEntry GetEntry(IReadOnlyList<IResultSetValue> reader)
|
||||||
{
|
{
|
||||||
|
@ -308,7 +302,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
index++;
|
index++;
|
||||||
if (reader[index].SQLiteType != SQLiteType.Null)
|
if (reader[index].SQLiteType != SQLiteType.Null)
|
||||||
{
|
{
|
||||||
info.Severity = (LogSeverity)Enum.Parse(typeof(LogSeverity), reader[index].ToString(), true);
|
info.Severity = (LogLevel)Enum.Parse(typeof(LogLevel), reader[index].ToString(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.AppBase
|
namespace Emby.Server.Implementations.AppBase
|
||||||
|
@ -13,10 +12,16 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
|
/// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected BaseApplicationPaths(string programDataPath, string appFolderPath)
|
protected BaseApplicationPaths(
|
||||||
|
string programDataPath,
|
||||||
|
string appFolderPath,
|
||||||
|
string logDirectoryPath = null,
|
||||||
|
string configurationDirectoryPath = null)
|
||||||
{
|
{
|
||||||
ProgramDataPath = programDataPath;
|
ProgramDataPath = programDataPath;
|
||||||
ProgramSystemPath = appFolderPath;
|
ProgramSystemPath = appFolderPath;
|
||||||
|
LogDirectoryPath = logDirectoryPath;
|
||||||
|
ConfigurationDirectoryPath = configurationDirectoryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ProgramDataPath { get; private set; }
|
public string ProgramDataPath { get; private set; }
|
||||||
|
@ -106,6 +111,11 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _log directory
|
||||||
|
/// </summary>
|
||||||
|
private string _logDirectoryPath;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path to the log directory
|
/// Gets the path to the log directory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -114,10 +124,26 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Path.Combine(ProgramDataPath, "logs");
|
if (string.IsNullOrEmpty(_logDirectoryPath))
|
||||||
|
{
|
||||||
|
_logDirectoryPath = Path.Combine(ProgramDataPath, "logs");
|
||||||
|
|
||||||
|
Directory.CreateDirectory(_logDirectoryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _logDirectoryPath;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_logDirectoryPath = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _config directory
|
||||||
|
/// </summary>
|
||||||
|
private string _configurationDirectoryPath;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path to the application configuration root directory
|
/// Gets the path to the application configuration root directory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -126,7 +152,18 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Path.Combine(ProgramDataPath, "config");
|
if (string.IsNullOrEmpty(_configurationDirectoryPath))
|
||||||
|
{
|
||||||
|
_configurationDirectoryPath = Path.Combine(ProgramDataPath, "config");
|
||||||
|
|
||||||
|
Directory.CreateDirectory(_configurationDirectoryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _configurationDirectoryPath;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_configurationDirectoryPath = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ using MediaBrowser.Common.Events;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.AppBase
|
namespace Emby.Server.Implementations.AppBase
|
||||||
|
@ -97,14 +97,14 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
/// Initializes a new instance of the <see cref="BaseConfigurationManager" /> class.
|
/// Initializes a new instance of the <see cref="BaseConfigurationManager" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="applicationPaths">The application paths.</param>
|
/// <param name="applicationPaths">The application paths.</param>
|
||||||
/// <param name="logManager">The log manager.</param>
|
/// <param name="loggerFactory">The logger factory.</param>
|
||||||
/// <param name="xmlSerializer">The XML serializer.</param>
|
/// <param name="xmlSerializer">The XML serializer.</param>
|
||||||
protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILogManager logManager, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
|
protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILoggerFactory loggerFactory, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
|
||||||
{
|
{
|
||||||
CommonApplicationPaths = applicationPaths;
|
CommonApplicationPaths = applicationPaths;
|
||||||
XmlSerializer = xmlSerializer;
|
XmlSerializer = xmlSerializer;
|
||||||
FileSystem = fileSystem;
|
FileSystem = fileSystem;
|
||||||
Logger = logManager.GetLogger(GetType().Name);
|
Logger = loggerFactory.CreateLogger(GetType().Name);
|
||||||
|
|
||||||
UpdateCachePath();
|
UpdateCachePath();
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SaveConfiguration()
|
public void SaveConfiguration()
|
||||||
{
|
{
|
||||||
Logger.Info("Saving system configuration");
|
Logger.LogInformation("Saving system configuration");
|
||||||
var path = CommonApplicationPaths.SystemConfigurationFilePath;
|
var path = CommonApplicationPaths.SystemConfigurationFilePath;
|
||||||
|
|
||||||
FileSystem.CreateDirectory(FileSystem.GetDirectoryName(path));
|
FileSystem.CreateDirectory(FileSystem.GetDirectoryName(path));
|
||||||
|
@ -259,7 +259,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error loading configuration file: {0}", ex, path);
|
Logger.LogError(ex, "Error loading configuration file: {path}", path);
|
||||||
|
|
||||||
return Activator.CreateInstance(configurationType);
|
return Activator.CreateInstance(configurationType);
|
||||||
}
|
}
|
||||||
|
@ -283,12 +283,11 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
validatingStore.Validate(currentConfiguration, configuration);
|
validatingStore.Validate(currentConfiguration, configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHelper.FireEventIfNotNull(NamedConfigurationUpdating, this, new ConfigurationUpdateEventArgs
|
NamedConfigurationUpdating?.Invoke( this, new ConfigurationUpdateEventArgs
|
||||||
{
|
{
|
||||||
Key = key,
|
Key = key,
|
||||||
NewConfiguration = configuration
|
NewConfiguration = configuration
|
||||||
|
});
|
||||||
}, Logger);
|
|
||||||
|
|
||||||
_configurations.AddOrUpdate(key, configuration, (k, v) => configuration);
|
_configurations.AddOrUpdate(key, configuration, (k, v) => configuration);
|
||||||
|
|
||||||
|
@ -305,12 +304,11 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
|
|
||||||
protected virtual void OnNamedConfigurationUpdated(string key, object configuration)
|
protected virtual void OnNamedConfigurationUpdated(string key, object configuration)
|
||||||
{
|
{
|
||||||
EventHelper.FireEventIfNotNull(NamedConfigurationUpdated, this, new ConfigurationUpdateEventArgs
|
NamedConfigurationUpdated?.Invoke(this, new ConfigurationUpdateEventArgs
|
||||||
{
|
{
|
||||||
Key = key,
|
Key = key,
|
||||||
NewConfiguration = configuration
|
NewConfiguration = configuration
|
||||||
|
});
|
||||||
}, Logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type GetConfigurationType(string key)
|
public Type GetConfigurationType(string key)
|
||||||
|
|
|
@ -10,7 +10,7 @@ using MediaBrowser.Model.Channels;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Extensions;
|
using MediaBrowser.Model.Extensions;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using MediaBrowser.Model.MediaInfo;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
|
@ -300,7 +300,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting channel information for {0}", ex, channelInfo.Name);
|
_logger.LogError(ex, "Error getting channel information for {0}", channelInfo.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
|
@ -484,10 +484,9 @@ namespace Emby.Server.Implementations.Channels
|
||||||
_libraryManager.CreateItem(item, null);
|
_libraryManager.CreateItem(item, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem)
|
await item.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem))
|
||||||
{
|
{
|
||||||
ForceSave = !isNew && forceUpdate
|
ForceSave = !isNew && forceUpdate
|
||||||
|
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
|
@ -709,7 +708,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
// Not yet sure why this is causing a problem
|
// Not yet sure why this is causing a problem
|
||||||
query.GroupByPresentationUniqueKey = false;
|
query.GroupByPresentationUniqueKey = false;
|
||||||
|
|
||||||
//_logger.Debug("GetChannelItemsInternal");
|
//_logger.LogDebug("GetChannelItemsInternal");
|
||||||
|
|
||||||
// null if came from cache
|
// null if came from cache
|
||||||
if (itemsResult != null)
|
if (itemsResult != null)
|
||||||
|
@ -849,7 +848,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error writing to channel cache file: {0}", ex, path);
|
_logger.LogError(ex, "Error writing to channel cache file: {path}", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,7 +901,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
private T GetItemById<T>(string idString, string channelName, out bool isNew)
|
private T GetItemById<T>(string idString, string channelName, out bool isNew)
|
||||||
where T : BaseItem, new()
|
where T : BaseItem, new()
|
||||||
{
|
{
|
||||||
var id = GetIdToHash(idString, channelName).GetMBId(typeof(T));
|
var id = _libraryManager.GetNewItemId(GetIdToHash(idString, channelName), typeof(T));
|
||||||
|
|
||||||
T item = null;
|
T item = null;
|
||||||
|
|
||||||
|
@ -912,7 +911,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error retrieving channel item from database", ex);
|
_logger.LogError(ex, "Error retrieving channel item from database");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
|
@ -1051,7 +1050,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
if (!info.TrailerTypes.SequenceEqual(trailer.TrailerTypes))
|
if (!info.TrailerTypes.SequenceEqual(trailer.TrailerTypes))
|
||||||
{
|
{
|
||||||
_logger.Debug("Forcing update due to TrailerTypes {0}", item.Name);
|
_logger.LogDebug("Forcing update due to TrailerTypes {0}", item.Name);
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
trailer.TrailerTypes = info.TrailerTypes.ToArray();
|
trailer.TrailerTypes = info.TrailerTypes.ToArray();
|
||||||
|
@ -1060,7 +1059,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
if (info.DateModified > item.DateModified)
|
if (info.DateModified > item.DateModified)
|
||||||
{
|
{
|
||||||
item.DateModified = info.DateModified;
|
item.DateModified = info.DateModified;
|
||||||
_logger.Debug("Forcing update due to DateModified {0}", item.Name);
|
_logger.LogDebug("Forcing update due to DateModified {0}", item.Name);
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1069,20 +1068,20 @@ namespace Emby.Server.Implementations.Channels
|
||||||
//{
|
//{
|
||||||
// item.ExternalEtag = info.Etag;
|
// item.ExternalEtag = info.Etag;
|
||||||
// forceUpdate = true;
|
// forceUpdate = true;
|
||||||
// _logger.Debug("Forcing update due to ExternalEtag {0}", item.Name);
|
// _logger.LogDebug("Forcing update due to ExternalEtag {0}", item.Name);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (!internalChannelId.Equals(item.ChannelId))
|
if (!internalChannelId.Equals(item.ChannelId))
|
||||||
{
|
{
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
_logger.Debug("Forcing update due to ChannelId {0}", item.Name);
|
_logger.LogDebug("Forcing update due to ChannelId {0}", item.Name);
|
||||||
}
|
}
|
||||||
item.ChannelId = internalChannelId;
|
item.ChannelId = internalChannelId;
|
||||||
|
|
||||||
if (!item.ParentId.Equals(parentFolderId))
|
if (!item.ParentId.Equals(parentFolderId))
|
||||||
{
|
{
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
_logger.Debug("Forcing update due to parent folder Id {0}", item.Name);
|
_logger.LogDebug("Forcing update due to parent folder Id {0}", item.Name);
|
||||||
}
|
}
|
||||||
item.ParentId = parentFolderId;
|
item.ParentId = parentFolderId;
|
||||||
|
|
||||||
|
@ -1092,7 +1091,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
if (!string.Equals(hasSeries.SeriesName, info.SeriesName, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(hasSeries.SeriesName, info.SeriesName, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
_logger.Debug("Forcing update due to SeriesName {0}", item.Name);
|
_logger.LogDebug("Forcing update due to SeriesName {0}", item.Name);
|
||||||
}
|
}
|
||||||
hasSeries.SeriesName = info.SeriesName;
|
hasSeries.SeriesName = info.SeriesName;
|
||||||
}
|
}
|
||||||
|
@ -1100,7 +1099,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
if (!string.Equals(item.ExternalId, info.Id, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(item.ExternalId, info.Id, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
_logger.Debug("Forcing update due to ExternalId {0}", item.Name);
|
_logger.LogDebug("Forcing update due to ExternalId {0}", item.Name);
|
||||||
}
|
}
|
||||||
item.ExternalId = info.Id;
|
item.ExternalId = info.Id;
|
||||||
|
|
||||||
|
@ -1125,7 +1124,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
if (!string.IsNullOrEmpty(info.ImageUrl) && !item.HasImage(ImageType.Primary))
|
if (!string.IsNullOrEmpty(info.ImageUrl) && !item.HasImage(ImageType.Primary))
|
||||||
{
|
{
|
||||||
item.SetImagePath(ImageType.Primary, info.ImageUrl);
|
item.SetImagePath(ImageType.Primary, info.ImageUrl);
|
||||||
_logger.Debug("Forcing update due to ImageUrl {0}", item.Name);
|
_logger.LogDebug("Forcing update due to ImageUrl {0}", item.Name);
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1134,7 +1133,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
if (item.Tags.Contains("livestream", StringComparer.OrdinalIgnoreCase))
|
if (item.Tags.Contains("livestream", StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
item.Tags = item.Tags.Except(new[] { "livestream" }, StringComparer.OrdinalIgnoreCase).ToArray();
|
item.Tags = item.Tags.Except(new[] { "livestream" }, StringComparer.OrdinalIgnoreCase).ToArray();
|
||||||
_logger.Debug("Forcing update due to Tags {0}", item.Name);
|
_logger.LogDebug("Forcing update due to Tags {0}", item.Name);
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1143,7 +1142,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
if (!item.Tags.Contains("livestream", StringComparer.OrdinalIgnoreCase))
|
if (!item.Tags.Contains("livestream", StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
item.Tags = item.Tags.Concat(new[] { "livestream" }).ToArray();
|
item.Tags = item.Tags.Concat(new[] { "livestream" }).ToArray();
|
||||||
_logger.Debug("Forcing update due to Tags {0}", item.Name);
|
_logger.LogDebug("Forcing update due to Tags {0}", item.Name);
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1178,7 +1177,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
if (isNew || forceUpdate || item.DateLastRefreshed == default(DateTime))
|
if (isNew || forceUpdate || item.DateLastRefreshed == default(DateTime))
|
||||||
{
|
{
|
||||||
_providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem), RefreshPriority.Normal);
|
_providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), RefreshPriority.Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
private void CleanChannel(Guid id, CancellationToken cancellationToken)
|
private void CleanChannel(Guid id, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.Info("Cleaning channel {0} from database", id);
|
_logger.LogInformation("Cleaning channel {0} from database", id);
|
||||||
|
|
||||||
// Delete all channel items
|
// Delete all channel items
|
||||||
var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
|
var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Common.Progress;
|
using MediaBrowser.Common.Progress;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
|
@ -54,7 +55,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Execute(System.Threading.CancellationToken cancellationToken, IProgress<double> progress)
|
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
var manager = (ChannelManager)_channelManager;
|
var manager = (ChannelManager)_channelManager;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -143,7 +143,7 @@ namespace Emby.Server.Implementations.Collections
|
||||||
|
|
||||||
if (options.ItemIdList.Length > 0)
|
if (options.ItemIdList.Length > 0)
|
||||||
{
|
{
|
||||||
AddToCollection(collection.Id, options.ItemIdList, false, new MetadataRefreshOptions(_fileSystem)
|
AddToCollection(collection.Id, options.ItemIdList, false, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem))
|
||||||
{
|
{
|
||||||
// The initial adding of items is going to create a local metadata file
|
// The initial adding of items is going to create a local metadata file
|
||||||
// This will cause internet metadata to be skipped as a result
|
// This will cause internet metadata to be skipped as a result
|
||||||
|
@ -152,15 +152,14 @@ namespace Emby.Server.Implementations.Collections
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(_fileSystem), RefreshPriority.High);
|
_providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), RefreshPriority.High);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHelper.FireEventIfNotNull(CollectionCreated, this, new CollectionCreatedEventArgs
|
CollectionCreated?.Invoke(this, new CollectionCreatedEventArgs
|
||||||
{
|
{
|
||||||
Collection = collection,
|
Collection = collection,
|
||||||
Options = options
|
Options = options
|
||||||
|
});
|
||||||
}, _logger);
|
|
||||||
|
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
@ -173,12 +172,12 @@ namespace Emby.Server.Implementations.Collections
|
||||||
|
|
||||||
public void AddToCollection(Guid collectionId, IEnumerable<string> ids)
|
public void AddToCollection(Guid collectionId, IEnumerable<string> ids)
|
||||||
{
|
{
|
||||||
AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(_fileSystem));
|
AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddToCollection(Guid collectionId, IEnumerable<Guid> ids)
|
public void AddToCollection(Guid collectionId, IEnumerable<Guid> ids)
|
||||||
{
|
{
|
||||||
AddToCollection(collectionId, ids.Select(i => i.ToString("N")), true, new MetadataRefreshOptions(_fileSystem));
|
AddToCollection(collectionId, ids.Select(i => i.ToString("N")), true, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddToCollection(Guid collectionId, IEnumerable<string> ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
|
private void AddToCollection(Guid collectionId, IEnumerable<string> ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
|
||||||
|
@ -230,12 +229,11 @@ namespace Emby.Server.Implementations.Collections
|
||||||
|
|
||||||
if (fireEvent)
|
if (fireEvent)
|
||||||
{
|
{
|
||||||
EventHelper.FireEventIfNotNull(ItemsAddedToCollection, this, new CollectionModifiedEventArgs
|
ItemsAddedToCollection?.Invoke(this, new CollectionModifiedEventArgs
|
||||||
{
|
{
|
||||||
Collection = collection,
|
Collection = collection,
|
||||||
ItemsChanged = itemList
|
ItemsChanged = itemList
|
||||||
|
});
|
||||||
}, _logger);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,7 +263,7 @@ namespace Emby.Server.Implementations.Collections
|
||||||
|
|
||||||
if (child == null)
|
if (child == null)
|
||||||
{
|
{
|
||||||
_logger.Warn("No collection title exists with the supplied Id");
|
_logger.LogWarning("No collection title exists with the supplied Id");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,17 +281,16 @@ namespace Emby.Server.Implementations.Collections
|
||||||
}
|
}
|
||||||
|
|
||||||
collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
|
collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
|
||||||
_providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(_fileSystem)
|
_providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem))
|
||||||
{
|
{
|
||||||
ForceSave = true
|
ForceSave = true
|
||||||
}, RefreshPriority.High);
|
}, RefreshPriority.High);
|
||||||
|
|
||||||
EventHelper.FireEventIfNotNull(ItemsRemovedFromCollection, this, new CollectionModifiedEventArgs
|
ItemsRemovedFromCollection?.Invoke(this, new CollectionModifiedEventArgs
|
||||||
{
|
{
|
||||||
Collection = collection,
|
Collection = collection,
|
||||||
ItemsChanged = itemList
|
ItemsChanged = itemList
|
||||||
|
});
|
||||||
}, _logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<BaseItem> CollapseItemsWithinBoxSets(IEnumerable<BaseItem> items, User user)
|
public IEnumerable<BaseItem> CollapseItemsWithinBoxSets(IEnumerable<BaseItem> items, User user)
|
||||||
|
@ -365,7 +362,7 @@ namespace Emby.Server.Implementations.Collections
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error creating camera uploads library", ex);
|
_logger.LogError(ex, "Error creating camera uploads library");
|
||||||
}
|
}
|
||||||
|
|
||||||
_config.Configuration.CollectionsUpgraded = true;
|
_config.Configuration.CollectionsUpgraded = true;
|
||||||
|
|
|
@ -1,22 +1,15 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using Emby.Server.Implementations.AppBase;
|
using Emby.Server.Implementations.AppBase;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Events;
|
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Configuration
|
namespace Emby.Server.Implementations.Configuration
|
||||||
{
|
{
|
||||||
|
@ -30,11 +23,11 @@ namespace Emby.Server.Implementations.Configuration
|
||||||
/// Initializes a new instance of the <see cref="ServerConfigurationManager" /> class.
|
/// Initializes a new instance of the <see cref="ServerConfigurationManager" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="applicationPaths">The application paths.</param>
|
/// <param name="applicationPaths">The application paths.</param>
|
||||||
/// <param name="logManager">The log manager.</param>
|
/// <param name="loggerFactory">The paramref name="loggerFactory" factory.</param>
|
||||||
/// <param name="xmlSerializer">The XML serializer.</param>
|
/// <param name="xmlSerializer">The XML serializer.</param>
|
||||||
/// <param name="fileSystem">The file system.</param>
|
/// <param name="fileSystem">The file system.</param>
|
||||||
public ServerConfigurationManager(IApplicationPaths applicationPaths, ILogManager logManager, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
|
public ServerConfigurationManager(IApplicationPaths applicationPaths, ILoggerFactory loggerFactory, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
|
||||||
: base(applicationPaths, logManager, xmlSerializer, fileSystem)
|
: base(applicationPaths, loggerFactory, xmlSerializer, fileSystem)
|
||||||
{
|
{
|
||||||
UpdateMetadataPath();
|
UpdateMetadataPath();
|
||||||
}
|
}
|
||||||
|
@ -143,7 +136,7 @@ namespace Emby.Server.Implementations.Configuration
|
||||||
ValidateMetadataPath(newConfig);
|
ValidateMetadataPath(newConfig);
|
||||||
ValidateSslCertificate(newConfig);
|
ValidateSslCertificate(newConfig);
|
||||||
|
|
||||||
EventHelper.FireEventIfNotNull(ConfigurationUpdating, this, new GenericEventArgs<ServerConfiguration> { Argument = newConfig }, Logger);
|
ConfigurationUpdating?.Invoke(this, new GenericEventArgs<ServerConfiguration> { Argument = newConfig });
|
||||||
|
|
||||||
base.ReplaceConfiguration(newConfiguration);
|
base.ReplaceConfiguration(newConfiguration);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using SQLitePCL.pretty;
|
using SQLitePCL.pretty;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SQLitePCL;
|
using SQLitePCL;
|
||||||
|
@ -75,22 +75,22 @@ namespace Emby.Server.Implementations.Data
|
||||||
if (!_versionLogged)
|
if (!_versionLogged)
|
||||||
{
|
{
|
||||||
_versionLogged = true;
|
_versionLogged = true;
|
||||||
Logger.Info("Sqlite version: " + SQLite3.Version);
|
Logger.LogInformation("Sqlite version: " + SQLite3.Version);
|
||||||
Logger.Info("Sqlite compiler options: " + string.Join(",", SQLite3.CompilerOptions.ToArray()));
|
Logger.LogInformation("Sqlite compiler options: " + string.Join(",", SQLite3.CompilerOptions.ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionFlags connectionFlags;
|
ConnectionFlags connectionFlags;
|
||||||
|
|
||||||
if (isReadOnly)
|
if (isReadOnly)
|
||||||
{
|
{
|
||||||
//Logger.Info("Opening read connection");
|
//Logger.LogInformation("Opening read connection");
|
||||||
//connectionFlags = ConnectionFlags.ReadOnly;
|
//connectionFlags = ConnectionFlags.ReadOnly;
|
||||||
connectionFlags = ConnectionFlags.Create;
|
connectionFlags = ConnectionFlags.Create;
|
||||||
connectionFlags |= ConnectionFlags.ReadWrite;
|
connectionFlags |= ConnectionFlags.ReadWrite;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Logger.Info("Opening write connection");
|
//Logger.LogInformation("Opening write connection");
|
||||||
connectionFlags = ConnectionFlags.Create;
|
connectionFlags = ConnectionFlags.Create;
|
||||||
connectionFlags |= ConnectionFlags.ReadWrite;
|
connectionFlags |= ConnectionFlags.ReadWrite;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
{
|
{
|
||||||
_defaultWal = db.Query("PRAGMA journal_mode").SelectScalarString().First();
|
_defaultWal = db.Query("PRAGMA journal_mode").SelectScalarString().First();
|
||||||
|
|
||||||
Logger.Info("Default journal_mode for {0} is {1}", DbFilePath, _defaultWal);
|
Logger.LogInformation("Default journal_mode for {0} is {1}", DbFilePath, _defaultWal);
|
||||||
}
|
}
|
||||||
|
|
||||||
var queries = new List<string>
|
var queries = new List<string>
|
||||||
|
@ -235,7 +235,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
db.ExecuteAll(string.Join(";", queries.ToArray()));
|
db.ExecuteAll(string.Join(";", queries.ToArray()));
|
||||||
Logger.Info("PRAGMA synchronous=" + db.Query("PRAGMA synchronous").SelectScalarString().First());
|
Logger.LogInformation("PRAGMA synchronous=" + db.Query("PRAGMA synchronous").SelectScalarString().First());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool EnableTempStoreMemory
|
protected virtual bool EnableTempStoreMemory
|
||||||
|
@ -323,7 +323,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error disposing database", ex);
|
Logger.LogError(ex, "Error disposing database");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -47,7 +47,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var numItems = itemIds.Count;
|
var numItems = itemIds.Count;
|
||||||
|
|
||||||
_logger.Debug("Cleaning {0} items with dead parent links", numItems);
|
_logger.LogDebug("Cleaning {0} items with dead parent links", numItems);
|
||||||
|
|
||||||
foreach (var itemId in itemIds)
|
foreach (var itemId in itemIds)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
_logger.Info("Cleaning item {0} type: {1} path: {2}", item.Name, item.GetType().Name, item.Path ?? string.Empty);
|
_logger.LogInformation("Cleaning item {0} type: {1} path: {2}", item.Name, item.GetType().Name, item.Path ?? string.Empty);
|
||||||
|
|
||||||
_libraryManager.DeleteItem(item, new DeleteOptions
|
_libraryManager.DeleteItem(item, new DeleteOptions
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@ using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using SQLitePCL.pretty;
|
using SQLitePCL.pretty;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error loading database file. Will reset and retry.", ex);
|
Logger.LogError(ex, "Error loading database file. Will reset and retry.");
|
||||||
|
|
||||||
FileSystem.DeleteFile(DbFilePath);
|
FileSystem.DeleteFile(DbFilePath);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.LiveTv;
|
using MediaBrowser.Model.LiveTv;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.Reflection;
|
using MediaBrowser.Model.Reflection;
|
||||||
|
@ -667,7 +667,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
var userDataKey = tuple.Item4;
|
var userDataKey = tuple.Item4;
|
||||||
|
|
||||||
SaveItem(item, topParent, userDataKey, saveItemStatement);
|
SaveItem(item, topParent, userDataKey, saveItemStatement);
|
||||||
//Logger.Debug(_saveItemCommand.CommandText);
|
//logger.LogDebug(_saveItemCommand.CommandText);
|
||||||
|
|
||||||
var inheritedTags = tuple.Item5;
|
var inheritedTags = tuple.Item5;
|
||||||
|
|
||||||
|
@ -886,12 +886,12 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
if (topParent != null)
|
if (topParent != null)
|
||||||
{
|
{
|
||||||
//Logger.Debug("Item {0} has top parent {1}", item.Id, topParent.Id);
|
//logger.LogDebug("Item {0} has top parent {1}", item.Id, topParent.Id);
|
||||||
saveItemStatement.TryBind("@TopParentId", topParent.Id.ToString("N"));
|
saveItemStatement.TryBind("@TopParentId", topParent.Id.ToString("N"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Logger.Debug("Item {0} has null top parent", item.Id);
|
//logger.LogDebug("Item {0} has null top parent", item.Id);
|
||||||
saveItemStatement.TryBindNull("@TopParentId");
|
saveItemStatement.TryBindNull("@TopParentId");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1230,7 +1230,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
//Logger.Info("Retrieving item {0}", id.ToString("N"));
|
//logger.LogInformation("Retrieving item {0}", id.ToString("N"));
|
||||||
using (WriteLock.Read())
|
using (WriteLock.Read())
|
||||||
{
|
{
|
||||||
using (var connection = CreateConnection(true))
|
using (var connection = CreateConnection(true))
|
||||||
|
@ -1345,7 +1345,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
{
|
{
|
||||||
//Logger.Debug("Unknown type {0}", typeString);
|
//logger.LogDebug("Unknown type {0}", typeString);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1364,7 +1364,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
}
|
}
|
||||||
catch (SerializationException ex)
|
catch (SerializationException ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error deserializing item", ex);
|
Logger.LogError(ex, "Error deserializing item");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2686,7 +2686,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
//Logger.Info("GetItemList: " + _environmentInfo.StackTrace);
|
//logger.LogInformation("GetItemList: " + _environmentInfo.StackTrace);
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
|
@ -2744,7 +2744,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
//Logger.Info("GetItemList: " + _environmentInfo.StackTrace);
|
//logger.LogInformation("GetItemList: " + _environmentInfo.StackTrace);
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
|
@ -2910,14 +2910,14 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
if (elapsed >= slowThreshold)
|
if (elapsed >= slowThreshold)
|
||||||
{
|
{
|
||||||
Logger.Debug("{2} query time (slow): {0}ms. Query: {1}",
|
Logger.LogDebug("{2} query time (slow): {0}ms. Query: {1}",
|
||||||
Convert.ToInt32(elapsed),
|
Convert.ToInt32(elapsed),
|
||||||
commandText,
|
commandText,
|
||||||
methodName);
|
methodName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Logger.Debug("{2} query time: {0}ms. Query: {1}",
|
//logger.LogDebug("{2} query time: {0}ms. Query: {1}",
|
||||||
// Convert.ToInt32(elapsed),
|
// Convert.ToInt32(elapsed),
|
||||||
// commandText,
|
// commandText,
|
||||||
// methodName);
|
// methodName);
|
||||||
|
@ -2942,7 +2942,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
TotalRecordCount = returnList.Count
|
TotalRecordCount = returnList.Count
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
//Logger.Info("GetItems: " + _environmentInfo.StackTrace);
|
//logger.LogInformation("GetItems: " + _environmentInfo.StackTrace);
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
|
@ -3216,7 +3216,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
//Logger.Info("GetItemIdsList: " + _environmentInfo.StackTrace);
|
//logger.LogInformation("GetItemIdsList: " + _environmentInfo.StackTrace);
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
|
@ -3376,7 +3376,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
TotalRecordCount = returnList.Count
|
TotalRecordCount = returnList.Count
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
//Logger.Info("GetItemIds: " + _environmentInfo.StackTrace);
|
//logger.LogInformation("GetItemIds: " + _environmentInfo.StackTrace);
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
|
@ -5565,7 +5565,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
//Logger.Info("GetItemValues: " + _environmentInfo.StackTrace);
|
//logger.LogInformation("GetItemValues: " + _environmentInfo.StackTrace);
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
|
@ -5734,7 +5734,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
||||||
var list = new List<Tuple<BaseItem, ItemCounts>>();
|
var list = new List<Tuple<BaseItem, ItemCounts>>();
|
||||||
var result = new QueryResult<Tuple<BaseItem, ItemCounts>>();
|
var result = new QueryResult<Tuple<BaseItem, ItemCounts>>();
|
||||||
|
|
||||||
//Logger.Info("GetItemValues {0}", string.Join(";", statementTexts.ToArray()));
|
//logger.LogInformation("GetItemValues {0}", string.Join(";", statementTexts.ToArray()));
|
||||||
var statements = PrepareAllSafe(db, statementTexts);
|
var statements = PrepareAllSafe(db, statementTexts);
|
||||||
|
|
||||||
if (!isReturningZeroItems)
|
if (!isReturningZeroItems)
|
||||||
|
|
|
@ -7,7 +7,7 @@ using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using SQLitePCL.pretty;
|
using SQLitePCL.pretty;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using SQLitePCL.pretty;
|
using SQLitePCL.pretty;
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error migrating users database", ex);
|
Logger.LogError(ex, "Error migrating users database");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Devices
|
namespace Emby.Server.Implementations.Devices
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ namespace Emby.Server.Implementations.Devices
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Error("Invalid value found in device id file");
|
_logger.LogError("Invalid value found in device id file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (DirectoryNotFoundException)
|
catch (DirectoryNotFoundException)
|
||||||
|
@ -45,7 +45,7 @@ namespace Emby.Server.Implementations.Devices
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error reading file", ex);
|
_logger.LogError(ex, "Error reading file");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -66,7 +66,7 @@ namespace Emby.Server.Implementations.Devices
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error writing to file", ex);
|
_logger.LogError(ex, "Error writing to file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Events;
|
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Devices;
|
using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Devices;
|
using MediaBrowser.Model.Devices;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
using MediaBrowser.Model.Extensions;
|
using MediaBrowser.Model.Extensions;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
|
@ -146,6 +145,7 @@ namespace Emby.Server.Implementations.Devices
|
||||||
|
|
||||||
}).Items;
|
}).Items;
|
||||||
|
|
||||||
|
// TODO: DeviceQuery doesn't seem to be used from client. Not even Swagger.
|
||||||
if (query.SupportsSync.HasValue)
|
if (query.SupportsSync.HasValue)
|
||||||
{
|
{
|
||||||
var val = query.SupportsSync.Value;
|
var val = query.SupportsSync.Value;
|
||||||
|
@ -253,14 +253,14 @@ namespace Emby.Server.Implementations.Devices
|
||||||
|
|
||||||
if (CameraImageUploaded != null)
|
if (CameraImageUploaded != null)
|
||||||
{
|
{
|
||||||
EventHelper.FireEventIfNotNull(CameraImageUploaded, this, new GenericEventArgs<CameraImageUploadInfo>
|
CameraImageUploaded?.Invoke(this, new GenericEventArgs<CameraImageUploadInfo>
|
||||||
{
|
{
|
||||||
Argument = new CameraImageUploadInfo
|
Argument = new CameraImageUploadInfo
|
||||||
{
|
{
|
||||||
Device = device,
|
Device = device,
|
||||||
FileInfo = file
|
FileInfo = file
|
||||||
}
|
}
|
||||||
}, _logger);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +434,7 @@ namespace Emby.Server.Implementations.Devices
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error creating camera uploads library", ex);
|
_logger.LogError(ex, "Error creating camera uploads library");
|
||||||
}
|
}
|
||||||
|
|
||||||
_config.Configuration.CameraUploadUpgraded = true;
|
_config.Configuration.CameraUploadUpgraded = true;
|
||||||
|
|
|
@ -16,7 +16,7 @@ using MediaBrowser.Controller.Sync;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -225,7 +225,7 @@ namespace Emby.Server.Implementations.Dto
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Have to use a catch-all unfortunately because some .net image methods throw plain Exceptions
|
// Have to use a catch-all unfortunately because some .net image methods throw plain Exceptions
|
||||||
_logger.ErrorException("Error generating PrimaryImageAspectRatio for {0}", ex, item.Name);
|
_logger.LogError(ex, "Error generating PrimaryImageAspectRatio for {itemName}", item.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,7 +547,7 @@ namespace Emby.Server.Implementations.Dto
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting {0} image info", ex, type);
|
_logger.LogError(ex, "Error getting {type} image info", type);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,7 +560,7 @@ namespace Emby.Server.Implementations.Dto
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting {0} image info for {1}", ex, image.Type, image.Path);
|
_logger.LogError(ex, "Error getting {imageType} image info for {path}", image.Type, image.Path);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,7 +619,7 @@ namespace Emby.Server.Implementations.Dto
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting person {0}", ex, c);
|
_logger.LogError(ex, "Error getting person {Name}", c);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1451,7 +1451,7 @@ namespace Emby.Server.Implementations.Dto
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
//_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, imageInfo.Path);
|
_logger.LogError(ex, "Failed to determine primary image aspect ratio for {0}", imageInfo.Path);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1464,7 +1464,7 @@ namespace Emby.Server.Implementations.Dto
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error in image enhancer: {0}", ex, enhancer.GetType().Name);
|
_logger.LogError(ex, "Error in image enhancer: {0}", enhancer.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -65,7 +65,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
DisposeTimer();
|
DisposeTimer();
|
||||||
|
|
||||||
_logger.Info("Automatically restarting the system because it is idle and a restart is required.");
|
_logger.LogInformation("Automatically restarting the system because it is idle and a restart is required.");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -73,7 +73,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error restarting server", ex);
|
_logger.LogError(ex, "Error restarting server");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting timers", ex);
|
_logger.LogError(ex, "Error getting timers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Threading;
|
using MediaBrowser.Model.Threading;
|
||||||
using Mono.Nat;
|
using Mono.Nat;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -29,9 +29,9 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
|
|
||||||
private NatManager _natManager;
|
private NatManager _natManager;
|
||||||
|
|
||||||
public ExternalPortForwarding(ILogManager logmanager, IServerApplicationHost appHost, IServerConfigurationManager config, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, ITimerFactory timerFactory)
|
public ExternalPortForwarding(ILoggerFactory loggerFactory, IServerApplicationHost appHost, IServerConfigurationManager config, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, ITimerFactory timerFactory)
|
||||||
{
|
{
|
||||||
_logger = logmanager.GetLogger("PortMapper");
|
_logger = loggerFactory.CreateLogger("PortMapper");
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
_config = config;
|
_config = config;
|
||||||
_deviceDiscovery = deviceDiscovery;
|
_deviceDiscovery = deviceDiscovery;
|
||||||
|
@ -84,7 +84,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
_logger.Debug("Starting NAT discovery");
|
_logger.LogDebug("Starting NAT discovery");
|
||||||
if (_natManager == null)
|
if (_natManager == null)
|
||||||
{
|
{
|
||||||
_natManager = new NatManager(_logger, _httpClient);
|
_natManager = new NatManager(_logger, _httpClient);
|
||||||
|
@ -139,7 +139,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
_usnsHandled.Add(identifier);
|
_usnsHandled.Add(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Found NAT device: " + identifier);
|
_logger.LogDebug("Found NAT device: " + identifier);
|
||||||
|
|
||||||
IPAddress address;
|
IPAddress address;
|
||||||
if (IPAddress.TryParse(info.Location.Host, out address))
|
if (IPAddress.TryParse(info.Location.Host, out address))
|
||||||
|
@ -166,6 +166,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_logger.LogError(ex, "Error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +217,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// Commenting out because users are reporting problems out of our control
|
// Commenting out because users are reporting problems out of our control
|
||||||
//_logger.ErrorException("Error creating port forwarding rules", ex);
|
//_logger.LogError(ex, "Error creating port forwarding rules");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,6 +254,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_logger.LogError(ex, "Error creating http port map");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,12 +264,13 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_logger.LogError(ex, "Error creating https port map");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task CreatePortMap(INatDevice device, int privatePort, int publicPort)
|
private Task CreatePortMap(INatDevice device, int privatePort, int publicPort)
|
||||||
{
|
{
|
||||||
_logger.Debug("Creating port map on local port {0} to public port {1} with device {2}", privatePort, publicPort, device.LocalAddress.ToString());
|
_logger.LogDebug("Creating port map on local port {0} to public port {1} with device {2}", privatePort, publicPort, device.LocalAddress.ToString());
|
||||||
|
|
||||||
return device.CreatePortMap(new Mapping(Protocol.Tcp, privatePort, publicPort)
|
return device.CreatePortMap(new Mapping(Protocol.Tcp, privatePort, publicPort)
|
||||||
{
|
{
|
||||||
|
@ -284,7 +287,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
|
|
||||||
private void DisposeNat()
|
private void DisposeNat()
|
||||||
{
|
{
|
||||||
_logger.Debug("Stopping NAT discovery");
|
_logger.LogDebug("Stopping NAT discovery");
|
||||||
|
|
||||||
if (_timer != null)
|
if (_timer != null)
|
||||||
{
|
{
|
||||||
|
@ -309,7 +312,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error stopping NAT Discovery", ex);
|
_logger.LogError(ex, "Error stopping NAT Discovery");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
using MediaBrowser.Controller;
|
|
||||||
using MediaBrowser.Controller.Plugins;
|
|
||||||
using MediaBrowser.Controller.Session;
|
|
||||||
using MediaBrowser.Model.Logging;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using MediaBrowser.Model.System;
|
|
||||||
using MediaBrowser.Model.Threading;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
|
||||||
{
|
|
||||||
public class KeepServerAwake : IServerEntryPoint
|
|
||||||
{
|
|
||||||
private readonly ISessionManager _sessionManager;
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
private ITimer _timer;
|
|
||||||
private readonly IServerApplicationHost _appHost;
|
|
||||||
private readonly ITimerFactory _timerFactory;
|
|
||||||
private readonly IPowerManagement _powerManagement;
|
|
||||||
|
|
||||||
public KeepServerAwake(ISessionManager sessionManager, ILogger logger, IServerApplicationHost appHost, ITimerFactory timerFactory, IPowerManagement powerManagement)
|
|
||||||
{
|
|
||||||
_sessionManager = sessionManager;
|
|
||||||
_logger = logger;
|
|
||||||
_appHost = appHost;
|
|
||||||
_timerFactory = timerFactory;
|
|
||||||
_powerManagement = powerManagement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Run()
|
|
||||||
{
|
|
||||||
_timer = _timerFactory.Create(OnTimerCallback, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnTimerCallback(object state)
|
|
||||||
{
|
|
||||||
var now = DateTime.UtcNow;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 15))
|
|
||||||
{
|
|
||||||
_powerManagement.PreventSystemStandby();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_powerManagement.AllowSystemStandby();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.ErrorException("Error resetting system standby timer", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_timer != null)
|
|
||||||
{
|
|
||||||
_timer.Dispose();
|
|
||||||
_timer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -331,7 +331,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error in GetLibraryUpdateInfo", ex);
|
_logger.LogError(ex, "Error in GetLibraryUpdateInfo");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error sending LibraryChanged message", ex);
|
_logger.LogError(ex, "Error sending LibraryChanged message");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
|
@ -66,7 +66,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error sending message", ex);
|
_logger.LogError(ex, "Error sending message");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
|
@ -15,10 +16,12 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask
|
public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask
|
||||||
{
|
{
|
||||||
|
private readonly ILogger _logger;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _user manager
|
/// The _user manager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
private IFileSystem _fileSystem;
|
private IFileSystem _fileSystem;
|
||||||
|
|
||||||
public string Name => "Refresh Users";
|
public string Name => "Refresh Users";
|
||||||
|
@ -41,8 +44,9 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
|
/// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RefreshUsersMetadata(IUserManager userManager, IFileSystem fileSystem)
|
public RefreshUsersMetadata(ILogger logger, IUserManager userManager, IFileSystem fileSystem)
|
||||||
{
|
{
|
||||||
|
_logger = logger;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +59,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
await user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken).ConfigureAwait(false);
|
await user.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,14 +156,10 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _sessionManager.SendMessageToAdminSessions(name, data, CancellationToken.None);
|
await _sessionManager.SendMessageToAdminSessions(name, data, CancellationToken.None);
|
||||||
}
|
|
||||||
catch (ObjectDisposedException)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
//Logger.ErrorException("Error sending message", ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,14 +168,10 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _sessionManager.SendMessageToUserSessions(new List<Guid> { user.Id }, name, data, CancellationToken.None);
|
await _sessionManager.SendMessageToUserSessions(new List<Guid> { user.Id }, name, data, CancellationToken.None);
|
||||||
}
|
|
||||||
catch (ObjectDisposedException)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
//Logger.ErrorException("Error sending message", ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using Emby.Server.Implementations.Browser;
|
using Emby.Server.Implementations.Browser;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
namespace Emby.Server.Implementations.EntryPoints
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using Emby.Server.Implementations.Udp;
|
using Emby.Server.Implementations.Udp;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
|
@ -45,9 +45,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
// ToDo: Fix This
|
|
||||||
return;
|
|
||||||
|
|
||||||
var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory);
|
var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -58,7 +55,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Failed to start UDP Server", ex);
|
_logger.LogError(ex, "Failed to start UDP Server");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
using MediaBrowser.Common.Extensions;
|
|
||||||
using MediaBrowser.Common.Net;
|
|
||||||
using MediaBrowser.Controller.Library;
|
|
||||||
using MediaBrowser.Controller.Plugins;
|
|
||||||
using MediaBrowser.Controller.Session;
|
|
||||||
using MediaBrowser.Model.Logging;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediaBrowser.Controller;
|
|
||||||
using MediaBrowser.Controller.Configuration;
|
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Class UsageEntryPoint
|
|
||||||
/// </summary>
|
|
||||||
public class UsageEntryPoint : IServerEntryPoint
|
|
||||||
{
|
|
||||||
private readonly IServerApplicationHost _applicationHost;
|
|
||||||
private readonly IHttpClient _httpClient;
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
private readonly ISessionManager _sessionManager;
|
|
||||||
private readonly IUserManager _userManager;
|
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<Guid, ClientInfo> _apps = new ConcurrentDictionary<Guid, ClientInfo>();
|
|
||||||
|
|
||||||
public UsageEntryPoint(ILogger logger, IServerApplicationHost applicationHost, IHttpClient httpClient, ISessionManager sessionManager, IUserManager userManager, IServerConfigurationManager config)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_applicationHost = applicationHost;
|
|
||||||
_httpClient = httpClient;
|
|
||||||
_sessionManager = sessionManager;
|
|
||||||
_userManager = userManager;
|
|
||||||
_config = config;
|
|
||||||
|
|
||||||
_sessionManager.SessionStarted += _sessionManager_SessionStarted;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _sessionManager_SessionStarted(object sender, SessionEventArgs e)
|
|
||||||
{
|
|
||||||
var session = e.SessionInfo;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(session.Client) &&
|
|
||||||
!string.IsNullOrEmpty(session.DeviceName) &&
|
|
||||||
!string.IsNullOrEmpty(session.DeviceId) &&
|
|
||||||
!string.IsNullOrEmpty(session.ApplicationVersion))
|
|
||||||
{
|
|
||||||
var keys = new List<string>
|
|
||||||
{
|
|
||||||
session.Client,
|
|
||||||
session.DeviceName,
|
|
||||||
session.DeviceId,
|
|
||||||
session.ApplicationVersion
|
|
||||||
};
|
|
||||||
|
|
||||||
var key = string.Join("_", keys.ToArray()).GetMD5();
|
|
||||||
|
|
||||||
ClientInfo info;
|
|
||||||
if (!_apps.TryGetValue(key, out info))
|
|
||||||
{
|
|
||||||
info = new ClientInfo
|
|
||||||
{
|
|
||||||
AppName = session.Client,
|
|
||||||
AppVersion = session.ApplicationVersion,
|
|
||||||
DeviceName = session.DeviceName,
|
|
||||||
DeviceId = session.DeviceId
|
|
||||||
};
|
|
||||||
|
|
||||||
_apps[key] = info;
|
|
||||||
|
|
||||||
if (_config.Configuration.EnableAnonymousUsageReporting)
|
|
||||||
{
|
|
||||||
Task.Run(() => ReportNewSession(info));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ReportNewSession(ClientInfo client)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await new UsageReporter(_applicationHost, _httpClient, _logger)
|
|
||||||
.ReportAppUsage(client, CancellationToken.None)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//_logger.ErrorException("Error sending anonymous usage statistics.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async void Run()
|
|
||||||
{
|
|
||||||
await Task.Delay(5000).ConfigureAwait(false);
|
|
||||||
OnTimerFired();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when [timer fired].
|
|
||||||
/// </summary>
|
|
||||||
private async void OnTimerFired()
|
|
||||||
{
|
|
||||||
if (!_config.Configuration.EnableAnonymousUsageReporting)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await new UsageReporter(_applicationHost, _httpClient, _logger)
|
|
||||||
.ReportServerUsage(CancellationToken.None)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//_logger.ErrorException("Error sending anonymous usage statistics.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_sessionManager.SessionStarted -= _sessionManager_SessionStarted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
using MediaBrowser.Common;
|
|
||||||
using MediaBrowser.Common.Net;
|
|
||||||
using MediaBrowser.Controller.Library;
|
|
||||||
using MediaBrowser.Model.Connect;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediaBrowser.Controller;
|
|
||||||
using MediaBrowser.Model.Logging;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
|
||||||
{
|
|
||||||
public class UsageReporter
|
|
||||||
{
|
|
||||||
private readonly IServerApplicationHost _applicationHost;
|
|
||||||
private readonly IHttpClient _httpClient;
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
private const string MbAdminUrl = "https://www.mb3admin.local/admin/";
|
|
||||||
|
|
||||||
public UsageReporter(IServerApplicationHost applicationHost, IHttpClient httpClient, ILogger logger)
|
|
||||||
{
|
|
||||||
_applicationHost = applicationHost;
|
|
||||||
_httpClient = httpClient;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ReportServerUsage(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
var data = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "feature", _applicationHost.Name },
|
|
||||||
{ "mac", _applicationHost.SystemId },
|
|
||||||
{ "serverid", _applicationHost.SystemId },
|
|
||||||
{ "deviceid", _applicationHost.SystemId },
|
|
||||||
{ "ver", _applicationHost.ApplicationVersion.ToString() },
|
|
||||||
{ "platform", _applicationHost.OperatingSystemDisplayName }
|
|
||||||
};
|
|
||||||
|
|
||||||
data["plugins"] = string.Join(",", _applicationHost.Plugins.Select(i => i.Id).ToArray());
|
|
||||||
|
|
||||||
var logErrors = false;
|
|
||||||
#if DEBUG
|
|
||||||
logErrors = true;
|
|
||||||
#endif
|
|
||||||
var options = new HttpRequestOptions
|
|
||||||
{
|
|
||||||
Url = MbAdminUrl + "service/registration/ping",
|
|
||||||
CancellationToken = cancellationToken,
|
|
||||||
|
|
||||||
// Seeing block length errors
|
|
||||||
EnableHttpCompression = false,
|
|
||||||
|
|
||||||
LogRequest = false,
|
|
||||||
LogErrors = logErrors,
|
|
||||||
BufferContent = false
|
|
||||||
};
|
|
||||||
|
|
||||||
options.SetPostData(data);
|
|
||||||
|
|
||||||
using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(app.DeviceId))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Client info must have a device Id");
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.Info("App Activity: app: {0}, version: {1}, deviceId: {2}, deviceName: {3}",
|
|
||||||
app.AppName ?? "Unknown App",
|
|
||||||
app.AppVersion ?? "Unknown",
|
|
||||||
app.DeviceId,
|
|
||||||
app.DeviceName ?? "Unknown");
|
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
var data = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "feature", app.AppName ?? "Unknown App" },
|
|
||||||
{ "serverid", _applicationHost.SystemId },
|
|
||||||
{ "deviceid", app.DeviceId },
|
|
||||||
{ "mac", app.DeviceId },
|
|
||||||
{ "ver", app.AppVersion ?? "Unknown" },
|
|
||||||
{ "platform", app.DeviceName },
|
|
||||||
};
|
|
||||||
|
|
||||||
var logErrors = false;
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
logErrors = true;
|
|
||||||
#endif
|
|
||||||
var options = new HttpRequestOptions
|
|
||||||
{
|
|
||||||
Url = MbAdminUrl + "service/registration/ping",
|
|
||||||
CancellationToken = cancellationToken,
|
|
||||||
|
|
||||||
// Seeing block length errors
|
|
||||||
EnableHttpCompression = false,
|
|
||||||
|
|
||||||
LogRequest = false,
|
|
||||||
LogErrors = logErrors,
|
|
||||||
BufferContent = false
|
|
||||||
};
|
|
||||||
|
|
||||||
options.SetPostData(data);
|
|
||||||
|
|
||||||
using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ClientInfo
|
|
||||||
{
|
|
||||||
public string AppName { get; set; }
|
|
||||||
public string AppVersion { get; set; }
|
|
||||||
public string DeviceName { get; set; }
|
|
||||||
public string DeviceId { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
@ -1,46 +1,33 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using MediaBrowser.Model.System;
|
using MediaBrowser.Model.System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EnvironmentInfo
|
namespace Emby.Server.Implementations.EnvironmentInfo
|
||||||
{
|
{
|
||||||
|
// TODO: Rework @bond
|
||||||
public class EnvironmentInfo : IEnvironmentInfo
|
public class EnvironmentInfo : IEnvironmentInfo
|
||||||
{
|
{
|
||||||
private Architecture? _customArchitecture;
|
public EnvironmentInfo(MediaBrowser.Model.System.OperatingSystem operatingSystem)
|
||||||
private MediaBrowser.Model.System.OperatingSystem? _customOperatingSystem;
|
|
||||||
|
|
||||||
public virtual MediaBrowser.Model.System.OperatingSystem OperatingSystem
|
|
||||||
{
|
{
|
||||||
get
|
OperatingSystem = operatingSystem;
|
||||||
{
|
|
||||||
if (_customOperatingSystem.HasValue)
|
|
||||||
{
|
|
||||||
return _customOperatingSystem.Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Environment.OSVersion.Platform)
|
public MediaBrowser.Model.System.OperatingSystem OperatingSystem { get; private set; }
|
||||||
{
|
|
||||||
case PlatformID.MacOSX:
|
|
||||||
return MediaBrowser.Model.System.OperatingSystem.OSX;
|
|
||||||
case PlatformID.Win32NT:
|
|
||||||
return MediaBrowser.Model.System.OperatingSystem.Windows;
|
|
||||||
case PlatformID.Unix:
|
|
||||||
return MediaBrowser.Model.System.OperatingSystem.Linux;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MediaBrowser.Model.System.OperatingSystem.Windows;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_customOperatingSystem = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string OperatingSystemName
|
public string OperatingSystemName
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Environment.OSVersion.Platform.ToString();
|
switch (OperatingSystem)
|
||||||
|
{
|
||||||
|
case MediaBrowser.Model.System.OperatingSystem.Android: return "Android";
|
||||||
|
case MediaBrowser.Model.System.OperatingSystem.BSD: return "BSD";
|
||||||
|
case MediaBrowser.Model.System.OperatingSystem.Linux: return "Linux";
|
||||||
|
case MediaBrowser.Model.System.OperatingSystem.OSX: return "macOS";
|
||||||
|
case MediaBrowser.Model.System.OperatingSystem.Windows: return "Windows";
|
||||||
|
default: throw new Exception($"Unknown OS {OperatingSystem}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,22 +47,7 @@ namespace Emby.Server.Implementations.EnvironmentInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Architecture SystemArchitecture
|
public Architecture SystemArchitecture { get { return RuntimeInformation.OSArchitecture; } }
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_customArchitecture.HasValue)
|
|
||||||
{
|
|
||||||
return _customArchitecture.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Environment.Is64BitOperatingSystem ? MediaBrowser.Model.System.Architecture.X64 : MediaBrowser.Model.System.Architecture.X86;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_customArchitecture = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetEnvironmentVariable(string name)
|
public string GetEnvironmentVariable(string name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -5,18 +5,16 @@ using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Cache;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Server.Implementations.IO;
|
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Controller.IO;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.HttpClientManager
|
namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
|
@ -125,59 +123,38 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
private WebRequest GetRequest(HttpRequestOptions options, string method)
|
private WebRequest GetRequest(HttpRequestOptions options, string method)
|
||||||
{
|
{
|
||||||
var url = options.Url;
|
string url = options.Url;
|
||||||
|
|
||||||
var uriAddress = new Uri(url);
|
Uri uriAddress = new Uri(url);
|
||||||
var userInfo = uriAddress.UserInfo;
|
string userInfo = uriAddress.UserInfo;
|
||||||
if (!string.IsNullOrWhiteSpace(userInfo))
|
if (!string.IsNullOrWhiteSpace(userInfo))
|
||||||
{
|
{
|
||||||
_logger.Info("Found userInfo in url: {0} ... url: {1}", userInfo, url);
|
_logger.LogInformation("Found userInfo in url: {0} ... url: {1}", userInfo, url);
|
||||||
url = url.Replace(userInfo + "@", string.Empty);
|
url = url.Replace(userInfo + "@", string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = CreateWebRequest(url);
|
WebRequest request = CreateWebRequest(url);
|
||||||
var httpWebRequest = request as HttpWebRequest;
|
|
||||||
|
|
||||||
if (httpWebRequest != null)
|
if (request is HttpWebRequest httpWebRequest)
|
||||||
{
|
{
|
||||||
AddRequestHeaders(httpWebRequest, options);
|
AddRequestHeaders(httpWebRequest, options);
|
||||||
|
|
||||||
if (options.EnableHttpCompression)
|
if (options.EnableHttpCompression)
|
||||||
{
|
|
||||||
if (options.DecompressionMethod.HasValue)
|
|
||||||
{
|
|
||||||
httpWebRequest.AutomaticDecompression = options.DecompressionMethod.Value == CompressionMethod.Gzip
|
|
||||||
? DecompressionMethods.GZip
|
|
||||||
: DecompressionMethods.Deflate;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate;
|
httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate;
|
||||||
|
if (options.DecompressionMethod.HasValue
|
||||||
|
&& options.DecompressionMethod.Value == CompressionMethod.Gzip)
|
||||||
|
{
|
||||||
|
httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
httpWebRequest.AutomaticDecompression = DecompressionMethods.None;
|
httpWebRequest.AutomaticDecompression = DecompressionMethods.None;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
httpWebRequest.KeepAlive = options.EnableKeepAlive;
|
||||||
|
|
||||||
|
|
||||||
request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
|
|
||||||
|
|
||||||
if (httpWebRequest != null)
|
|
||||||
{
|
|
||||||
if (options.EnableKeepAlive)
|
|
||||||
{
|
|
||||||
httpWebRequest.KeepAlive = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
request.Method = method;
|
|
||||||
request.Timeout = options.TimeoutMs;
|
|
||||||
|
|
||||||
if (httpWebRequest != null)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(options.Host))
|
if (!string.IsNullOrEmpty(options.Host))
|
||||||
{
|
{
|
||||||
httpWebRequest.Host = options.Host;
|
httpWebRequest.Host = options.Host;
|
||||||
|
@ -189,6 +166,11 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
|
||||||
|
|
||||||
|
request.Method = method;
|
||||||
|
request.Timeout = options.TimeoutMs;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(userInfo))
|
if (!string.IsNullOrWhiteSpace(userInfo))
|
||||||
{
|
{
|
||||||
var parts = userInfo.Split(':');
|
var parts = userInfo.Split(':');
|
||||||
|
@ -215,7 +197,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
var hasUserAgent = false;
|
var hasUserAgent = false;
|
||||||
|
|
||||||
foreach (var header in options.RequestHeaders.ToList())
|
foreach (var header in options.RequestHeaders)
|
||||||
{
|
{
|
||||||
if (string.Equals(header.Key, "Accept", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(header.Key, "Accept", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -379,10 +361,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// TODO: We can always put this in the options object if needed
|
var bytes = options.RequestContentBytes ?? Encoding.UTF8.GetBytes(options.RequestContent ?? string.Empty);
|
||||||
var requestEncoding = Encoding.UTF8;
|
|
||||||
|
|
||||||
var bytes = options.RequestContentBytes ?? requestEncoding.GetBytes(options.RequestContent ?? string.Empty);
|
|
||||||
|
|
||||||
var contentType = options.RequestContentType ?? "application/x-www-form-urlencoded";
|
var contentType = options.RequestContentType ?? "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
|
@ -392,7 +371,6 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
}
|
}
|
||||||
|
|
||||||
httpWebRequest.ContentType = contentType;
|
httpWebRequest.ContentType = contentType;
|
||||||
|
|
||||||
httpWebRequest.ContentLength = bytes.Length;
|
httpWebRequest.ContentLength = bytes.Length;
|
||||||
(await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)).Write(bytes, 0, bytes.Length);
|
(await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)).Write(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
|
@ -409,10 +387,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < TimeoutSeconds)
|
if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < TimeoutSeconds)
|
||||||
{
|
{
|
||||||
if (options.ResourcePool != null)
|
options.ResourcePool?.Release();
|
||||||
{
|
|
||||||
options.ResourcePool.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
|
throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
|
||||||
}
|
}
|
||||||
|
@ -421,11 +396,11 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
if (options.LogRequestAsDebug)
|
if (options.LogRequestAsDebug)
|
||||||
{
|
{
|
||||||
_logger.Debug("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url);
|
_logger.LogDebug("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Info("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url);
|
_logger.LogInformation("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +432,6 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
using (var stream = httpResponse.GetResponseStream())
|
using (var stream = httpResponse.GetResponseStream())
|
||||||
{
|
{
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
|
|
||||||
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
||||||
|
|
||||||
memoryStream.Position = 0;
|
memoryStream.Position = 0;
|
||||||
|
@ -476,10 +450,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (options.ResourcePool != null)
|
options.ResourcePool?.Release();
|
||||||
{
|
|
||||||
options.ResourcePool.Release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,13 +459,9 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
var responseInfo = new HttpResponseInfo(disposable)
|
var responseInfo = new HttpResponseInfo(disposable)
|
||||||
{
|
{
|
||||||
Content = content,
|
Content = content,
|
||||||
|
|
||||||
StatusCode = httpResponse.StatusCode,
|
StatusCode = httpResponse.StatusCode,
|
||||||
|
|
||||||
ContentType = httpResponse.ContentType,
|
ContentType = httpResponse.ContentType,
|
||||||
|
|
||||||
ContentLength = contentLength,
|
ContentLength = contentLength,
|
||||||
|
|
||||||
ResponseUrl = httpResponse.ResponseUri.ToString()
|
ResponseUrl = httpResponse.ResponseUri.ToString()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -511,11 +478,8 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
var responseInfo = new HttpResponseInfo
|
var responseInfo = new HttpResponseInfo
|
||||||
{
|
{
|
||||||
TempFilePath = tempFile,
|
TempFilePath = tempFile,
|
||||||
|
|
||||||
StatusCode = httpResponse.StatusCode,
|
StatusCode = httpResponse.StatusCode,
|
||||||
|
|
||||||
ContentType = httpResponse.ContentType,
|
ContentType = httpResponse.ContentType,
|
||||||
|
|
||||||
ContentLength = contentLength
|
ContentLength = contentLength
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -595,11 +559,11 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
if (options.LogRequestAsDebug)
|
if (options.LogRequestAsDebug)
|
||||||
{
|
{
|
||||||
_logger.Debug("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
|
_logger.LogDebug("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Info("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
|
_logger.LogInformation("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,24 +583,22 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
var contentLength = GetContentLength(httpResponse);
|
var contentLength = GetContentLength(httpResponse);
|
||||||
|
|
||||||
if (!contentLength.HasValue)
|
if (contentLength.HasValue)
|
||||||
{
|
|
||||||
// We're not able to track progress
|
|
||||||
using (var stream = httpResponse.GetResponseStream())
|
|
||||||
{
|
|
||||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
|
||||||
{
|
|
||||||
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
||||||
{
|
{
|
||||||
await httpResponse.GetResponseStream().CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
await httpResponse.GetResponseStream().CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We're not able to track progress
|
||||||
|
using (var stream = httpResponse.GetResponseStream())
|
||||||
|
using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
||||||
|
{
|
||||||
|
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
options.Progress.Report(100);
|
options.Progress.Report(100);
|
||||||
|
|
||||||
|
@ -650,10 +612,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (options.ResourcePool != null)
|
options.ResourcePool?.Release();
|
||||||
{
|
|
||||||
options.ResourcePool.Release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,7 +644,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
if (options.LogErrors)
|
if (options.LogErrors)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error " + webException.Status + " getting response from " + options.Url, webException);
|
_logger.LogError(webException, "Error {status} getting response from {url}", webException.Status, options.Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
var exception = new HttpException(webException.Message, webException);
|
var exception = new HttpException(webException.Message, webException);
|
||||||
|
@ -723,7 +682,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
if (options.LogErrors)
|
if (options.LogErrors)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
_logger.LogError(ex, "Error getting response from {url}", options.Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ex;
|
return ex;
|
||||||
|
@ -789,7 +748,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
if (options.LogErrors)
|
if (options.LogErrors)
|
||||||
{
|
{
|
||||||
_logger.Error(msg);
|
_logger.LogError(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
client.LastTimeout = DateTime.UtcNow;
|
client.LastTimeout = DateTime.UtcNow;
|
||||||
|
@ -810,8 +769,11 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
var isSuccessful = statusCode >= HttpStatusCode.OK && statusCode <= (HttpStatusCode)299;
|
var isSuccessful = statusCode >= HttpStatusCode.OK && statusCode <= (HttpStatusCode)299;
|
||||||
|
|
||||||
if (!isSuccessful)
|
if (isSuccessful)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (options.LogErrorResponseBody)
|
if (options.LogErrorResponseBody)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -824,7 +786,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
var msg = reader.ReadToEnd();
|
var msg = reader.ReadToEnd();
|
||||||
|
|
||||||
_logger.Error(msg);
|
_logger.LogError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -834,12 +796,12 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new HttpException(response.StatusDescription)
|
throw new HttpException(response.StatusDescription)
|
||||||
{
|
{
|
||||||
StatusCode = response.StatusCode
|
StatusCode = response.StatusCode
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Task<WebResponse> GetResponseAsync(WebRequest request, TimeSpan timeout)
|
private Task<WebResponse> GetResponseAsync(WebRequest request, TimeSpan timeout)
|
||||||
{
|
{
|
||||||
|
@ -859,15 +821,12 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
private static void TimeoutCallback(object state, bool timedOut)
|
private static void TimeoutCallback(object state, bool timedOut)
|
||||||
{
|
{
|
||||||
if (timedOut)
|
if (timedOut && state != null)
|
||||||
{
|
{
|
||||||
WebRequest request = (WebRequest)state;
|
WebRequest request = (WebRequest)state;
|
||||||
if (state != null)
|
|
||||||
{
|
|
||||||
request.Abort();
|
request.Abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private class TaskCallback
|
private class TaskCallback
|
||||||
{
|
{
|
||||||
|
@ -880,13 +839,13 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
public void OnError(Task<WebResponse> task)
|
public void OnError(Task<WebResponse> task)
|
||||||
{
|
{
|
||||||
if (task.Exception != null)
|
if (task.Exception == null)
|
||||||
{
|
{
|
||||||
taskCompletion.TrySetException(task.Exception);
|
taskCompletion.TrySetException(Enumerable.Empty<Exception>());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
taskCompletion.TrySetException(new List<Exception>());
|
taskCompletion.TrySetException(task.Exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
var rangeString = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
|
var rangeString = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
|
||||||
Headers["Content-Range"] = rangeString;
|
Headers["Content-Range"] = rangeString;
|
||||||
|
|
||||||
Logger.Info("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
|
Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -173,7 +173,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
if (extension == null || !SkipLogExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
|
if (extension == null || !SkipLogExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Logger.Debug("Transmit file {0}", path);
|
Logger.LogDebug("Transmit file {0}", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
//var count = FileShare == FileShareMode.ReadWrite ? TotalContentLength : 0;
|
//var count = FileShare == FileShareMode.ReadWrite ? TotalContentLength : 0;
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -16,17 +15,12 @@ using Emby.Server.Implementations.Services;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Common.Security;
|
using MediaBrowser.Common.Security;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.Cryptography;
|
|
||||||
using MediaBrowser.Model.Extensions;
|
using MediaBrowser.Model.Extensions;
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using MediaBrowser.Model.Net;
|
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
using MediaBrowser.Model.System;
|
|
||||||
using MediaBrowser.Model.Text;
|
using MediaBrowser.Model.Text;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using Emby.Server.Implementations.Net;
|
using Emby.Server.Implementations.Net;
|
||||||
using MediaBrowser.Common.Events;
|
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.HttpServer
|
namespace Emby.Server.Implementations.HttpServer
|
||||||
|
@ -184,7 +178,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
if (WebSocketConnected != null)
|
if (WebSocketConnected != null)
|
||||||
{
|
{
|
||||||
EventHelper.FireEventIfNotNull(WebSocketConnected, this, new GenericEventArgs<IWebSocketConnection>(connection), _logger);
|
WebSocketConnected?.Invoke(this, new GenericEventArgs<IWebSocketConnection>(connection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,11 +246,11 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
if (logExceptionStackTrace)
|
if (logExceptionStackTrace)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error processing request", ex);
|
_logger.LogError(ex, "Error processing request");
|
||||||
}
|
}
|
||||||
else if (logExceptionMessage)
|
else if (logExceptionMessage)
|
||||||
{
|
{
|
||||||
_logger.Error(ex.Message);
|
_logger.LogError(ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
var httpRes = httpReq.Response;
|
var httpRes = httpReq.Response;
|
||||||
|
@ -272,9 +266,9 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
httpRes.ContentType = "text/html";
|
httpRes.ContentType = "text/html";
|
||||||
await Write(httpRes, NormalizeExceptionMessage(ex.Message)).ConfigureAwait(false);
|
await Write(httpRes, NormalizeExceptionMessage(ex.Message)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception errorEx)
|
||||||
{
|
{
|
||||||
//_logger.ErrorException("Error this.ProcessRequest(context)(Exception while writing error to the response)", errorEx);
|
_logger.LogError(errorEx, "Error this.ProcessRequest(context)(Exception while writing error to the response)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,10 +314,10 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
if (_listener != null)
|
if (_listener != null)
|
||||||
{
|
{
|
||||||
_logger.Info("Stopping HttpListener...");
|
_logger.LogInformation("Stopping HttpListener...");
|
||||||
var task = _listener.Stop();
|
var task = _listener.Stop();
|
||||||
Task.WaitAll(task);
|
Task.WaitAll(task);
|
||||||
_logger.Info("HttpListener stopped");
|
_logger.LogInformation("HttpListener stopped");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,12 +707,12 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
var pathParts = pathInfo.TrimStart('/').Split('/');
|
var pathParts = pathInfo.TrimStart('/').Split('/');
|
||||||
if (pathParts.Length == 0)
|
if (pathParts.Length == 0)
|
||||||
{
|
{
|
||||||
_logger.Error("Path parts empty for PathInfo: {0}, Url: {1}", pathInfo, httpReq.RawUrl);
|
_logger.LogError("Path parts empty for PathInfo: {pathInfo}, Url: {RawUrl}", pathInfo, httpReq.RawUrl);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string contentType;
|
string contentType;
|
||||||
var restPath = ServiceHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, _logger, out contentType);
|
var restPath = ServiceHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, out contentType);
|
||||||
|
|
||||||
if (restPath != null)
|
if (restPath != null)
|
||||||
{
|
{
|
||||||
|
@ -729,7 +723,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Error("Could not find handler for {0}", pathInfo);
|
_logger.LogError("Could not find handler for {pathInfo}", pathInfo);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,7 +777,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
ServiceController = new ServiceController();
|
ServiceController = new ServiceController();
|
||||||
|
|
||||||
_logger.Info("Calling ServiceStack AppHost.Init");
|
_logger.LogInformation("Calling ServiceStack AppHost.Init");
|
||||||
|
|
||||||
var types = services.Select(r => r.GetType()).ToArray();
|
var types = services.Select(r => r.GetType()).ToArray();
|
||||||
|
|
||||||
|
@ -853,7 +847,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
//using (var reader = new StreamReader(stream))
|
//using (var reader = new StreamReader(stream))
|
||||||
//{
|
//{
|
||||||
// var json = reader.ReadToEnd();
|
// var json = reader.ReadToEnd();
|
||||||
// Logger.Info(json);
|
// logger.LogInformation(json);
|
||||||
// return _jsonSerializer.DeserializeFromString(json, type);
|
// return _jsonSerializer.DeserializeFromString(json, type);
|
||||||
//}
|
//}
|
||||||
return _jsonSerializer.DeserializeFromStreamAsync(stream, type);
|
return _jsonSerializer.DeserializeFromStreamAsync(stream, type);
|
||||||
|
@ -919,7 +913,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
//_logger.Debug("Websocket message received: {0}", result.MessageType);
|
_logger.LogDebug("Websocket message received: {0}", result.MessageType);
|
||||||
|
|
||||||
var tasks = _webSocketListeners.Select(i => Task.Run(async () =>
|
var tasks = _webSocketListeners.Select(i => Task.Run(async () =>
|
||||||
{
|
{
|
||||||
|
@ -929,7 +923,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("{0} failed processing WebSocket message {1}", ex, i.GetType().Name, result.MessageType ?? string.Empty);
|
_logger.LogError(ex, "{0} failed processing WebSocket message {1}", i.GetType().Name, result.MessageType ?? string.Empty);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -37,12 +37,12 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="HttpResultFactory" /> class.
|
/// Initializes a new instance of the <see cref="HttpResultFactory" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IBrotliCompressor brotliCompressor)
|
public HttpResultFactory(ILoggerFactory loggerfactory, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IBrotliCompressor brotliCompressor)
|
||||||
{
|
{
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_jsonSerializer = jsonSerializer;
|
_jsonSerializer = jsonSerializer;
|
||||||
_brotliCompressor = brotliCompressor;
|
_brotliCompressor = brotliCompressor;
|
||||||
_logger = logManager.GetLogger("HttpResultFactory");
|
_logger = loggerfactory.CreateLogger("HttpResultFactory");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
|
@ -11,7 +11,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
if (headers == null)
|
if (headers == null)
|
||||||
{
|
{
|
||||||
logger.Info("{0} {1}. UserAgent: {2}", "HTTP " + method, url, userAgent ?? string.Empty);
|
logger.LogInformation("{0} {1}. UserAgent: {2}", "HTTP " + method, url, userAgent ?? string.Empty);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("HTTP {0} {1}. {2}", method, url, headerText);
|
logger.LogInformation("HTTP {0} {1}. {2}", method, url, headerText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
//var headerText = headers == null ? string.Empty : "Headers: " + string.Join(", ", headers.Where(i => i.Name.IndexOf("Access-", StringComparison.OrdinalIgnoreCase) == -1).Select(i => i.Name + "=" + i.Value).ToArray());
|
//var headerText = headers == null ? string.Empty : "Headers: " + string.Join(", ", headers.Where(i => i.Name.IndexOf("Access-", StringComparison.OrdinalIgnoreCase) == -1).Select(i => i.Name + "=" + i.Value).ToArray());
|
||||||
var headerText = string.Empty;
|
var headerText = string.Empty;
|
||||||
logger.Info("HTTP Response {0} to {1}. Time: {2}{3}. {4} {5}", statusCode, endPoint, Convert.ToInt32(durationMs).ToString(CultureInfo.InvariantCulture), logSuffix, url, headerText);
|
logger.LogInformation("HTTP Response {0} to {1}. Time: {2}{3}. {4} {5}", statusCode, endPoint, Convert.ToInt32(durationMs).ToString(CultureInfo.InvariantCulture), logSuffix, url, headerText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -34,7 +34,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error processing request for {0}", exception, req.RawUrl);
|
_logger.LogError(exception, "Error processing request for {RawUrl}", req.RawUrl);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(exception.Message))
|
if (!string.IsNullOrEmpty(exception.Message))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using MediaBrowser.Common.Events;
|
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Model.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using System;
|
using System;
|
||||||
|
@ -118,7 +117,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
void socket_Closed(object sender, EventArgs e)
|
void socket_Closed(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
EventHelper.FireEventIfNotNull(Closed, this, EventArgs.Empty, _logger);
|
Closed?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -180,7 +179,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
if (!message.StartsWith("{", StringComparison.OrdinalIgnoreCase))
|
if (!message.StartsWith("{", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
// This info is useful sometimes but also clogs up the log
|
// This info is useful sometimes but also clogs up the log
|
||||||
//_logger.Error("Received web socket message that is not a json structure: " + message);
|
_logger.LogDebug("Received web socket message that is not a json structure: {message}", message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +203,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error processing web socket message", ex);
|
_logger.LogError(ex, "Error processing web socket message");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|