Merge branch 'master' into sessionmanager

This commit is contained in:
Bond-009 2020-02-19 21:07:09 +01:00 committed by GitHub
commit 0f173e1778
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
409 changed files with 2132 additions and 777 deletions

View file

@ -10,6 +10,19 @@ assignees: ''
**Describe the bug** **Describe the bug**
<!-- A clear and concise description of what the bug is. --> <!-- A clear and concise description of what the bug is. -->
**System (please complete the following information):**
- OS: [e.g. Debian, Windows]
- Virtualization: [e.g. Docker, KVM, LXC]
- Clients: [Browser, Android, Fire Stick, etc.]
- Browser: [e.g. Firefox 72, Chrome 80, Safari 13]
- Jellyfin Version: [e.g. 10.4.3, nightly 20191231]
- Playback: [Direct Play, Remux, Direct Stream, Transcode]
- Installed Plugins: [e.g. none, Fanart, Anime, etc.]
- Reverse Proxy: [e.g. none, nginx, apache, etc.]
- Base URL: [e.g. none, yes: /example]
- Networking: [e.g. Host, Bridge/NAT]
- Storage: [e.g. local, NFS, cloud]
**To Reproduce** **To Reproduce**
<!-- Steps to reproduce the behavior: --> <!-- Steps to reproduce the behavior: -->
1. Go to '...' 1. Go to '...'
@ -26,12 +39,5 @@ assignees: ''
**Screenshots** **Screenshots**
<!-- If applicable, add screenshots to help explain your problem. --> <!-- If applicable, add screenshots to help explain your problem. -->
**System (please complete the following information):**
- OS: [e.g. Docker, Debian, Windows]
- Browser: [e.g. Firefox, Chrome, Safari]
- Jellyfin Version: [e.g. 10.0.1]
- Installed Plugins: [e.g. none, Fanart, Anime, etc.]
- Reverse proxy: [e.g. no, nginx, apache, etc.]
**Additional context** **Additional context**
<!-- Add any other context about the problem here. --> <!-- Add any other context about the problem here. -->

View file

@ -32,8 +32,10 @@
- [nevado](https://github.com/nevado) - [nevado](https://github.com/nevado)
- [mark-monteiro](https://github.com/mark-monteiro) - [mark-monteiro](https://github.com/mark-monteiro)
- [ullmie02](https://github.com/ullmie02) - [ullmie02](https://github.com/ullmie02)
- [geilername](https://github.com/geilername)
- [pR0Ps](https://github.com/pR0Ps) - [pR0Ps](https://github.com/pR0Ps)
# Emby Contributors # Emby Contributors
- [LukePulverenti](https://github.com/LukePulverenti) - [LukePulverenti](https://github.com/LukePulverenti)

View file

@ -3,7 +3,7 @@ ARG FFMPEG_VERSION=latest
FROM node:alpine as web-builder FROM node:alpine as web-builder
ARG JELLYFIN_WEB_VERSION=master ARG JELLYFIN_WEB_VERSION=master
RUN apk add curl \ RUN apk add curl git \
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& cd jellyfin-web-* \ && cd jellyfin-web-* \
&& yarn install \ && yarn install \

View file

@ -1,9 +1,13 @@
# DESIGNED FOR BUILDING ON AMD64 ONLY
#####################################
# Requires binfm_misc registration
# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
ARG DOTNET_VERSION=3.1 ARG DOTNET_VERSION=3.1
FROM node:alpine as web-builder FROM node:alpine as web-builder
ARG JELLYFIN_WEB_VERSION=master ARG JELLYFIN_WEB_VERSION=master
RUN apk add curl \ RUN apk add curl git \
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& cd jellyfin-web-* \ && cd jellyfin-web-* \
&& yarn install \ && yarn install \
@ -21,7 +25,9 @@ RUN find . -type d -name obj | xargs -r rm -r
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none"
FROM debian:buster-slim FROM multiarch/qemu-user-static:x86_64-arm as qemu
FROM arm32v7/debian:buster-slim
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
RUN apt-get update \ RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \ && apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
libssl-dev ca-certificates \ libssl-dev ca-certificates \

View file

@ -1,9 +1,13 @@
# DESIGNED FOR BUILDING ON AMD64 ONLY
#####################################
# Requires binfm_misc registration
# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
ARG DOTNET_VERSION=3.1 ARG DOTNET_VERSION=3.1
FROM node:alpine as web-builder FROM node:alpine as web-builder
ARG JELLYFIN_WEB_VERSION=master ARG JELLYFIN_WEB_VERSION=master
RUN apk add curl \ RUN apk add curl git \
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& cd jellyfin-web-* \ && cd jellyfin-web-* \
&& yarn install \ && yarn install \
@ -20,8 +24,9 @@ RUN find . -type d -name obj | xargs -r rm -r
# Build # Build
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm64 "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm64 "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none"
FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu
FROM debian:buster-slim FROM arm64v8/debian:buster-slim
COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin
RUN apt-get update \ RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \ && apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
libssl-dev ca-certificates \ libssl-dev ca-certificates \

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Linq; using System.Linq;
using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;

View file

@ -1,3 +1,5 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
namespace Emby.Dlna.Common namespace Emby.Dlna.Common
{ {

View file

@ -1,3 +1,7 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Globalization;
namespace Emby.Dlna.Common namespace Emby.Dlna.Common
{ {
@ -13,9 +17,14 @@ namespace Emby.Dlna.Common
public string Depth { get; set; } public string Depth { get; set; }
/// <inheritdoc />
public override string ToString() public override string ToString()
{ {
return string.Format("{0}x{1}", Height, Width); return string.Format(
CultureInfo.InvariantCulture,
"{0}x{1}",
Height,
Width);
} }
} }
} }

View file

@ -1,3 +1,5 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
namespace Emby.Dlna.Common namespace Emby.Dlna.Common
{ {
@ -13,9 +15,8 @@ namespace Emby.Dlna.Common
public string EventSubUrl { get; set; } public string EventSubUrl { get; set; }
/// <inheritdoc />
public override string ToString() public override string ToString()
{ => ServiceId;
return string.Format("{0}", ServiceId);
}
} }
} }

View file

@ -1,21 +1,25 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
namespace Emby.Dlna.Common namespace Emby.Dlna.Common
{ {
public class ServiceAction public class ServiceAction
{ {
public string Name { get; set; }
public List<Argument> ArgumentList { get; set; }
public override string ToString()
{
return Name;
}
public ServiceAction() public ServiceAction()
{ {
ArgumentList = new List<Argument>(); ArgumentList = new List<Argument>();
} }
public string Name { get; set; }
public List<Argument> ArgumentList { get; set; }
/// <inheritdoc />
public override string ToString()
{
return Name;
}
} }
} }

View file

@ -1,9 +1,17 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
namespace Emby.Dlna.Common namespace Emby.Dlna.Common
{ {
public class StateVariable public class StateVariable
{ {
public StateVariable()
{
AllowedValues = Array.Empty<string>();
}
public string Name { get; set; } public string Name { get; set; }
public string DataType { get; set; } public string DataType { get; set; }
@ -12,14 +20,8 @@ namespace Emby.Dlna.Common
public string[] AllowedValues { get; set; } public string[] AllowedValues { get; set; }
/// <inheritdoc />
public override string ToString() public override string ToString()
{ => Name;
return Name;
}
public StateVariable()
{
AllowedValues = Array.Empty<string>();
}
} }
} }

View file

@ -1,17 +1,10 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
namespace Emby.Dlna.Configuration namespace Emby.Dlna.Configuration
{ {
public class DlnaOptions public class DlnaOptions
{ {
public bool EnablePlayTo { get; set; }
public bool EnableServer { get; set; }
public bool EnableDebugLog { get; set; }
public bool BlastAliveMessages { get; set; }
public bool SendOnlyMatchedHost { get; set; }
public int ClientDiscoveryIntervalSeconds { get; set; }
public int BlastAliveMessageIntervalSeconds { get; set; }
public string DefaultUserId { get; set; }
public DlnaOptions() public DlnaOptions()
{ {
EnablePlayTo = true; EnablePlayTo = true;
@ -21,5 +14,21 @@ namespace Emby.Dlna.Configuration
ClientDiscoveryIntervalSeconds = 60; ClientDiscoveryIntervalSeconds = 60;
BlastAliveMessageIntervalSeconds = 1800; BlastAliveMessageIntervalSeconds = 1800;
} }
public bool EnablePlayTo { get; set; }
public bool EnableServer { get; set; }
public bool EnableDebugLog { get; set; }
public bool BlastAliveMessages { get; set; }
public bool SendOnlyMatchedHost { get; set; }
public int ClientDiscoveryIntervalSeconds { get; set; }
public int BlastAliveMessageIntervalSeconds { get; set; }
public string DefaultUserId { get; set; }
} }
} }

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
using Emby.Dlna.Configuration; using Emby.Dlna.Configuration;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Threading.Tasks; using System.Threading.Tasks;
using Emby.Dlna.Service; using Emby.Dlna.Service;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
using Emby.Dlna.Common; using Emby.Dlna.Common;
using Emby.Dlna.Service; using Emby.Dlna.Service;

View file

@ -1,5 +1,9 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Xml;
using Emby.Dlna.Service; using Emby.Dlna.Service;
using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
@ -12,29 +16,28 @@ namespace Emby.Dlna.ConnectionManager
{ {
private readonly DeviceProfile _profile; private readonly DeviceProfile _profile;
protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, IDictionary<string, string> methodParams)
{
if (string.Equals(methodName, "GetProtocolInfo", StringComparison.OrdinalIgnoreCase))
{
return HandleGetProtocolInfo();
}
throw new ResourceNotFoundException("Unexpected control request name: " + methodName);
}
private IEnumerable<KeyValuePair<string, string>> HandleGetProtocolInfo()
{
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "Source", _profile.ProtocolInfo },
{ "Sink", "" }
};
}
public ControlHandler(IServerConfigurationManager config, ILogger logger, DeviceProfile profile) public ControlHandler(IServerConfigurationManager config, ILogger logger, DeviceProfile profile)
: base(config, logger) : base(config, logger)
{ {
_profile = profile; _profile = profile;
} }
/// <inheritdoc />
protected override void WriteResult(string methodName, IDictionary<string, string> methodParams, XmlWriter xmlWriter)
{
if (string.Equals(methodName, "GetProtocolInfo", StringComparison.OrdinalIgnoreCase))
{
HandleGetProtocolInfo(xmlWriter);
return;
}
throw new ResourceNotFoundException("Unexpected control request name: " + methodName);
}
private void HandleGetProtocolInfo(XmlWriter xmlWriter)
{
xmlWriter.WriteElementString("Source", _profile.ProtocolInfo);
xmlWriter.WriteElementString("Sink", string.Empty);
}
} }
} }

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
using Emby.Dlna.Common; using Emby.Dlna.Common;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Emby.Dlna.Service; using Emby.Dlna.Service;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
using Emby.Dlna.Common; using Emby.Dlna.Common;
using Emby.Dlna.Service; using Emby.Dlna.Service;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
@ -44,7 +47,6 @@ namespace Emby.Dlna.ContentDirectory
private const string NS_UPNP = "urn:schemas-upnp-org:metadata-1-0/upnp/"; private const string NS_UPNP = "urn:schemas-upnp-org:metadata-1-0/upnp/";
private readonly int _systemUpdateId; private readonly int _systemUpdateId;
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private readonly DidlBuilder _didlBuilder; private readonly DidlBuilder _didlBuilder;
@ -58,7 +60,8 @@ namespace Emby.Dlna.ContentDirectory
string accessToken, string accessToken,
IImageProcessor imageProcessor, IImageProcessor imageProcessor,
IUserDataManager userDataManager, IUserDataManager userDataManager,
User user, int systemUpdateId, User user,
int systemUpdateId,
IServerConfigurationManager config, IServerConfigurationManager config,
ILocalizationManager localization, ILocalizationManager localization,
IMediaSourceManager mediaSourceManager, IMediaSourceManager mediaSourceManager,
@ -79,114 +82,129 @@ namespace Emby.Dlna.ContentDirectory
_didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, Logger, mediaEncoder); _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, Logger, mediaEncoder);
} }
protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, IDictionary<string, string> methodParams) /// <inheritdoc />
protected override void WriteResult(string methodName, IDictionary<string, string> methodParams, XmlWriter xmlWriter)
{ {
var deviceId = "test"; const string DeviceId = "test";
var user = _user;
if (string.Equals(methodName, "GetSearchCapabilities", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "GetSearchCapabilities", StringComparison.OrdinalIgnoreCase))
return HandleGetSearchCapabilities(); {
HandleGetSearchCapabilities(xmlWriter);
return;
}
if (string.Equals(methodName, "GetSortCapabilities", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "GetSortCapabilities", StringComparison.OrdinalIgnoreCase))
return HandleGetSortCapabilities(); {
HandleGetSortCapabilities(xmlWriter);
return;
}
if (string.Equals(methodName, "GetSortExtensionCapabilities", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "GetSortExtensionCapabilities", StringComparison.OrdinalIgnoreCase))
return HandleGetSortExtensionCapabilities(); {
HandleGetSortExtensionCapabilities(xmlWriter);
return;
}
if (string.Equals(methodName, "GetSystemUpdateID", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "GetSystemUpdateID", StringComparison.OrdinalIgnoreCase))
return HandleGetSystemUpdateID(); {
HandleGetSystemUpdateID(xmlWriter);
return;
}
if (string.Equals(methodName, "Browse", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "Browse", StringComparison.OrdinalIgnoreCase))
return HandleBrowse(methodParams, user, deviceId); {
HandleBrowse(xmlWriter, methodParams, DeviceId);
return;
}
if (string.Equals(methodName, "X_GetFeatureList", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "X_GetFeatureList", StringComparison.OrdinalIgnoreCase))
return HandleXGetFeatureList(); {
HandleXGetFeatureList(xmlWriter);
return;
}
if (string.Equals(methodName, "GetFeatureList", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "GetFeatureList", StringComparison.OrdinalIgnoreCase))
return HandleGetFeatureList(); {
HandleGetFeatureList(xmlWriter);
return;
}
if (string.Equals(methodName, "X_SetBookmark", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "X_SetBookmark", StringComparison.OrdinalIgnoreCase))
return HandleXSetBookmark(methodParams, user); {
HandleXSetBookmark(methodParams);
return;
}
if (string.Equals(methodName, "Search", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "Search", StringComparison.OrdinalIgnoreCase))
return HandleSearch(methodParams, user, deviceId); {
HandleSearch(xmlWriter, methodParams, DeviceId);
return;
}
if (string.Equals(methodName, "X_BrowseByLetter", StringComparison.OrdinalIgnoreCase)) if (string.Equals(methodName, "X_BrowseByLetter", StringComparison.OrdinalIgnoreCase))
return HandleX_BrowseByLetter(methodParams, user, deviceId); {
HandleXBrowseByLetter(xmlWriter, methodParams, DeviceId);
return;
}
throw new ResourceNotFoundException("Unexpected control request name: " + methodName); throw new ResourceNotFoundException("Unexpected control request name: " + methodName);
} }
private IEnumerable<KeyValuePair<string, string>> HandleXSetBookmark(IDictionary<string, string> sparams, User user) private void HandleXSetBookmark(IDictionary<string, string> sparams)
{ {
var id = sparams["ObjectID"]; var id = sparams["ObjectID"];
var serverItem = GetItemFromObjectId(id, user); var serverItem = GetItemFromObjectId(id, _user);
var item = serverItem.Item; var item = serverItem.Item;
var newbookmark = int.Parse(sparams["PosSecond"], _usCulture); var newbookmark = int.Parse(sparams["PosSecond"], CultureInfo.InvariantCulture);
var userdata = _userDataManager.GetUserData(user, item); var userdata = _userDataManager.GetUserData(_user, item);
userdata.PlaybackPositionTicks = TimeSpan.FromSeconds(newbookmark).Ticks; userdata.PlaybackPositionTicks = TimeSpan.FromSeconds(newbookmark).Ticks;
_userDataManager.SaveUserData(user, item, userdata, UserDataSaveReason.TogglePlayed, _userDataManager.SaveUserData(_user, item, userdata, UserDataSaveReason.TogglePlayed,
CancellationToken.None); CancellationToken.None);
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
} }
private IEnumerable<KeyValuePair<string, string>> HandleGetSearchCapabilities() private void HandleGetSearchCapabilities(XmlWriter xmlWriter)
{ {
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) xmlWriter.WriteElementString(
{ "SearchCaps",
{ "SearchCaps", "res@resolution,res@size,res@duration,dc:title,dc:creator,upnp:actor,upnp:artist,upnp:genre,upnp:album,dc:date,upnp:class,@id,@refID,@protocolInfo,upnp:author,dc:description,pv:avKeywords" } "res@resolution,res@size,res@duration,dc:title,dc:creator,upnp:actor,upnp:artist,upnp:genre,upnp:album,dc:date,upnp:class,@id,@refID,@protocolInfo,upnp:author,dc:description,pv:avKeywords");
};
} }
private IEnumerable<KeyValuePair<string, string>> HandleGetSortCapabilities() private void HandleGetSortCapabilities(XmlWriter xmlWriter)
{ {
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) xmlWriter.WriteElementString(
{ "SortCaps",
{ "SortCaps", "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating" } "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating");
};
} }
private IEnumerable<KeyValuePair<string, string>> HandleGetSortExtensionCapabilities() private void HandleGetSortExtensionCapabilities(XmlWriter xmlWriter)
{ {
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) xmlWriter.WriteElementString(
{ "SortExtensionCaps",
{ "SortExtensionCaps", "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating" } "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating");
};
} }
private IEnumerable<KeyValuePair<string, string>> HandleGetSystemUpdateID() private void HandleGetSystemUpdateID(XmlWriter xmlWriter)
{ {
var headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); xmlWriter.WriteElementString("Id", _systemUpdateId.ToString(CultureInfo.InvariantCulture));
headers.Add("Id", _systemUpdateId.ToString(_usCulture));
return headers;
} }
private IEnumerable<KeyValuePair<string, string>> HandleGetFeatureList() private void HandleGetFeatureList(XmlWriter xmlWriter)
{ {
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) xmlWriter.WriteElementString("FeatureList", WriteFeatureListXml());
{
{ "FeatureList", GetFeatureListXml() }
};
} }
private IEnumerable<KeyValuePair<string, string>> HandleXGetFeatureList() private void HandleXGetFeatureList(XmlWriter xmlWriter)
{ => HandleGetFeatureList(xmlWriter);
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "FeatureList", GetFeatureListXml() }
};
}
private string GetFeatureListXml() private string WriteFeatureListXml()
{ {
// TODO: clean this up
var builder = new StringBuilder(); var builder = new StringBuilder();
builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
@ -213,7 +231,7 @@ namespace Emby.Dlna.ContentDirectory
return defaultValue; return defaultValue;
} }
private IEnumerable<KeyValuePair<string, string>> HandleBrowse(IDictionary<string, string> sparams, User user, string deviceId) private void HandleBrowse(XmlWriter xmlWriter, IDictionary<string, string> sparams, string deviceId)
{ {
var id = sparams["ObjectID"]; var id = sparams["ObjectID"];
var flag = sparams["BrowseFlag"]; var flag = sparams["BrowseFlag"];
@ -237,101 +255,95 @@ namespace Emby.Dlna.ContentDirectory
start = startVal; start = startVal;
} }
var settings = new XmlWriterSettings
{
Encoding = Encoding.UTF8,
CloseOutput = false,
OmitXmlDeclaration = true,
ConformanceLevel = ConformanceLevel.Fragment
};
StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8);
int totalCount; int totalCount;
var dlnaOptions = _config.GetDlnaConfiguration(); using (StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8))
using (var writer = XmlWriter.Create(builder, settings))
{ {
//writer.WriteStartDocument(); var settings = new XmlWriterSettings()
writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL);
writer.WriteAttributeString("xmlns", "dc", null, NS_DC);
writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA);
writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP);
//didl.SetAttribute("xmlns:sec", NS_SEC);
DidlBuilder.WriteXmlRootAttributes(_profile, writer);
var serverItem = GetItemFromObjectId(id, user);
var item = serverItem.Item;
if (string.Equals(flag, "BrowseMetadata"))
{ {
totalCount = 1; Encoding = Encoding.UTF8,
CloseOutput = false,
OmitXmlDeclaration = true,
ConformanceLevel = ConformanceLevel.Fragment
};
if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue) using (var writer = XmlWriter.Create(builder, settings))
{
var childrenResult = GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount);
_didlBuilder.WriteFolderElement(writer, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id);
}
else
{
_didlBuilder.WriteItemElement(dlnaOptions, writer, item, user, null, null, deviceId, filter);
}
provided++;
}
else
{ {
var childrenResult = GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount); writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL);
totalCount = childrenResult.TotalRecordCount;
provided = childrenResult.Items.Count; writer.WriteAttributeString("xmlns", "dc", null, NS_DC);
writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA);
writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP);
foreach (var i in childrenResult.Items) DidlBuilder.WriteXmlRootAttributes(_profile, writer);
var serverItem = GetItemFromObjectId(id, _user);
var item = serverItem.Item;
if (string.Equals(flag, "BrowseMetadata", StringComparison.Ordinal))
{ {
var childItem = i.Item; totalCount = 1;
var displayStubType = i.StubType;
if (childItem.IsDisplayedAsFolder || displayStubType.HasValue) if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue)
{ {
var childCount = (GetUserItems(childItem, displayStubType, user, sortCriteria, null, 0)) var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount);
.TotalRecordCount;
_didlBuilder.WriteFolderElement(writer, childItem, displayStubType, item, childCount, filter); _didlBuilder.WriteFolderElement(writer, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id);
} }
else else
{ {
_didlBuilder.WriteItemElement(dlnaOptions, writer, childItem, user, item, serverItem.StubType, deviceId, filter); var dlnaOptions = _config.GetDlnaConfiguration();
_didlBuilder.WriteItemElement(dlnaOptions, writer, item, _user, null, null, deviceId, filter);
}
provided++;
}
else
{
var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount);
totalCount = childrenResult.TotalRecordCount;
provided = childrenResult.Items.Count;
var dlnaOptions = _config.GetDlnaConfiguration();
foreach (var i in childrenResult.Items)
{
var childItem = i.Item;
var displayStubType = i.StubType;
if (childItem.IsDisplayedAsFolder || displayStubType.HasValue)
{
var childCount = GetUserItems(childItem, displayStubType, _user, sortCriteria, null, 0)
.TotalRecordCount;
_didlBuilder.WriteFolderElement(writer, childItem, displayStubType, item, childCount, filter);
}
else
{
_didlBuilder.WriteItemElement(dlnaOptions, writer, childItem, _user, item, serverItem.StubType, deviceId, filter);
}
} }
} }
writer.WriteFullEndElement();
} }
writer.WriteFullEndElement(); xmlWriter.WriteElementString("Result", builder.ToString());
//writer.WriteEndDocument();
} }
var resXML = builder.ToString(); xmlWriter.WriteElementString("NumberReturned", provided.ToString(CultureInfo.InvariantCulture));
xmlWriter.WriteElementString("TotalMatches", totalCount.ToString(CultureInfo.InvariantCulture));
return new[] xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(CultureInfo.InvariantCulture));
{
new KeyValuePair<string,string>("Result", resXML),
new KeyValuePair<string,string>("NumberReturned", provided.ToString(_usCulture)),
new KeyValuePair<string,string>("TotalMatches", totalCount.ToString(_usCulture)),
new KeyValuePair<string,string>("UpdateID", _systemUpdateId.ToString(_usCulture))
};
} }
private IEnumerable<KeyValuePair<string, string>> HandleX_BrowseByLetter(IDictionary<string, string> sparams, User user, string deviceId) private void HandleXBrowseByLetter(XmlWriter xmlWriter, IDictionary<string, string> sparams, string deviceId)
{ {
// TODO: Implement this method // TODO: Implement this method
return HandleSearch(sparams, user, deviceId); HandleSearch(xmlWriter, sparams, deviceId);
} }
private IEnumerable<KeyValuePair<string, string>> HandleSearch(IDictionary<string, string> sparams, User user, string deviceId) private void HandleSearch(XmlWriter xmlWriter, IDictionary<string, string> sparams, string deviceId)
{ {
var searchCriteria = new SearchCriteria(GetValueOrDefault(sparams, "SearchCriteria", "")); var searchCriteria = new SearchCriteria(GetValueOrDefault(sparams, "SearchCriteria", ""));
var sortCriteria = new SortCriteria(GetValueOrDefault(sparams, "SortCriteria", "")); var sortCriteria = new SortCriteria(GetValueOrDefault(sparams, "SortCriteria", ""));
@ -354,99 +366,86 @@ namespace Emby.Dlna.ContentDirectory
start = startVal; start = startVal;
} }
var settings = new XmlWriterSettings QueryResult<BaseItem> childrenResult;
using (StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8))
{ {
Encoding = Encoding.UTF8, var settings = new XmlWriterSettings()
CloseOutput = false,
OmitXmlDeclaration = true,
ConformanceLevel = ConformanceLevel.Fragment
};
StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8);
int totalCount = 0;
int provided = 0;
using (var writer = XmlWriter.Create(builder, settings))
{
//writer.WriteStartDocument();
writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL);
writer.WriteAttributeString("xmlns", "dc", null, NS_DC);
writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA);
writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP);
//didl.SetAttribute("xmlns:sec", NS_SEC);
DidlBuilder.WriteXmlRootAttributes(_profile, writer);
var serverItem = GetItemFromObjectId(sparams["ContainerID"], user);
var item = serverItem.Item;
var childrenResult = (GetChildrenSorted(item, user, searchCriteria, sortCriteria, start, requestedCount));
totalCount = childrenResult.TotalRecordCount;
provided = childrenResult.Items.Count;
var dlnaOptions = _config.GetDlnaConfiguration();
foreach (var i in childrenResult.Items)
{ {
if (i.IsDisplayedAsFolder) Encoding = Encoding.UTF8,
{ CloseOutput = false,
var childCount = (GetChildrenSorted(i, user, searchCriteria, sortCriteria, null, 0)) OmitXmlDeclaration = true,
.TotalRecordCount; ConformanceLevel = ConformanceLevel.Fragment
};
_didlBuilder.WriteFolderElement(writer, i, null, item, childCount, filter); using (var writer = XmlWriter.Create(builder, settings))
} {
else writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL);
writer.WriteAttributeString("xmlns", "dc", null, NS_DC);
writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA);
writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP);
DidlBuilder.WriteXmlRootAttributes(_profile, writer);
var serverItem = GetItemFromObjectId(sparams["ContainerID"], _user);
var item = serverItem.Item;
childrenResult = GetChildrenSorted(item, _user, searchCriteria, sortCriteria, start, requestedCount);
var dlnaOptions = _config.GetDlnaConfiguration();
foreach (var i in childrenResult.Items)
{ {
_didlBuilder.WriteItemElement(dlnaOptions, writer, i, user, item, serverItem.StubType, deviceId, filter); if (i.IsDisplayedAsFolder)
{
var childCount = GetChildrenSorted(i, _user, searchCriteria, sortCriteria, null, 0)
.TotalRecordCount;
_didlBuilder.WriteFolderElement(writer, i, null, item, childCount, filter);
}
else
{
_didlBuilder.WriteItemElement(dlnaOptions, writer, i, _user, item, serverItem.StubType, deviceId, filter);
}
} }
writer.WriteFullEndElement();
} }
writer.WriteFullEndElement(); xmlWriter.WriteElementString("Result", builder.ToString());
//writer.WriteEndDocument();
} }
var resXML = builder.ToString(); xmlWriter.WriteElementString("NumberReturned", childrenResult.Items.Count.ToString(CultureInfo.InvariantCulture));
xmlWriter.WriteElementString("TotalMatches", childrenResult.TotalRecordCount.ToString(CultureInfo.InvariantCulture));
return new List<KeyValuePair<string, string>> xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(CultureInfo.InvariantCulture));
{
new KeyValuePair<string,string>("Result", resXML),
new KeyValuePair<string,string>("NumberReturned", provided.ToString(_usCulture)),
new KeyValuePair<string,string>("TotalMatches", totalCount.ToString(_usCulture)),
new KeyValuePair<string,string>("UpdateID", _systemUpdateId.ToString(_usCulture))
};
} }
private QueryResult<BaseItem> GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit) private QueryResult<BaseItem> GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit)
{ {
var folder = (Folder)item; var folder = (Folder)item;
var sortOrders = new List<(string, SortOrder)>(); var sortOrders = folder.IsPreSorted
if (!folder.IsPreSorted) ? Array.Empty<(string, SortOrder)>()
{ : new[] { (ItemSortBy.SortName, sort.SortOrder) };
sortOrders.Add((ItemSortBy.SortName, sort.SortOrder));
}
var mediaTypes = new List<string>(); string[] mediaTypes = Array.Empty<string>();
bool? isFolder = null; bool? isFolder = null;
if (search.SearchType == SearchType.Audio) if (search.SearchType == SearchType.Audio)
{ {
mediaTypes.Add(MediaType.Audio); mediaTypes = new[] { MediaType.Audio };
isFolder = false; isFolder = false;
} }
else if (search.SearchType == SearchType.Video) else if (search.SearchType == SearchType.Video)
{ {
mediaTypes.Add(MediaType.Video); mediaTypes = new[] { MediaType.Video };
isFolder = false; isFolder = false;
} }
else if (search.SearchType == SearchType.Image) else if (search.SearchType == SearchType.Image)
{ {
mediaTypes.Add(MediaType.Photo); mediaTypes = new[] { MediaType.Photo };
isFolder = false; isFolder = false;
} }
else if (search.SearchType == SearchType.Playlist) else if (search.SearchType == SearchType.Playlist)
@ -470,7 +469,7 @@ namespace Emby.Dlna.ContentDirectory
IsMissing = false, IsMissing = false,
ExcludeItemTypes = new[] { typeof(Book).Name }, ExcludeItemTypes = new[] { typeof(Book).Name },
IsFolder = isFolder, IsFolder = isFolder,
MediaTypes = mediaTypes.ToArray(), MediaTypes = mediaTypes,
DtoOptions = GetDtoOptions() DtoOptions = GetDtoOptions()
}); });
} }
@ -1304,11 +1303,11 @@ namespace Emby.Dlna.ContentDirectory
StubType? stubType = null; StubType? stubType = null;
// After using PlayTo, MediaMonkey sends a request to the server trying to get item info // After using PlayTo, MediaMonkey sends a request to the server trying to get item info
const string paramsSrch = "Params="; const string ParamsSrch = "Params=";
var paramsIndex = id.IndexOf(paramsSrch, StringComparison.OrdinalIgnoreCase); var paramsIndex = id.IndexOf(ParamsSrch, StringComparison.OrdinalIgnoreCase);
if (paramsIndex != -1) if (paramsIndex != -1)
{ {
id = id.Substring(paramsIndex + paramsSrch.Length); id = id.Substring(paramsIndex + ParamsSrch.Length);
var parts = id.Split(';'); var parts = id.Split(';');
id = parts[23]; id = parts[23];

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
using Emby.Dlna.Common; using Emby.Dlna.Common;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.IO; using System.IO;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;

View file

@ -1,18 +1,21 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
namespace Emby.Dlna namespace Emby.Dlna
{ {
public class ControlResponse public class ControlResponse
{ {
public ControlResponse()
{
Headers = new Dictionary<string, string>();
}
public IDictionary<string, string> Headers { get; set; } public IDictionary<string, string> Headers { get; set; }
public string Xml { get; set; } public string Xml { get; set; }
public bool IsSuccessful { get; set; } public bool IsSuccessful { get; set; }
public ControlResponse()
{
Headers = new Dictionary<string, string>();
}
} }
} }

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
@ -631,7 +634,7 @@ namespace Emby.Dlna.Didl
{ {
if (item.PremiereDate.HasValue) if (item.PremiereDate.HasValue)
{ {
AddValue(writer, "dc", "date", item.PremiereDate.Value.ToString("o"), NS_DC); AddValue(writer, "dc", "date", item.PremiereDate.Value.ToString("o", CultureInfo.InvariantCulture), NS_DC);
} }
} }

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Extensions;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;

View file

@ -15,6 +15,19 @@
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>netstandard2.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release'" >true</TreatWarningsAsErrors>
</PropertyGroup>
<!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View file

@ -1,17 +1,21 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
namespace Emby.Dlna namespace Emby.Dlna
{ {
public class EventSubscriptionResponse public class EventSubscriptionResponse
{ {
public string Content { get; set; }
public string ContentType { get; set; }
public Dictionary<string, string> Headers { get; set; }
public EventSubscriptionResponse() public EventSubscriptionResponse()
{ {
Headers = new Dictionary<string, string>(); Headers = new Dictionary<string, string>();
} }
public string Content { get; set; }
public string ContentType { get; set; }
public Dictionary<string, string> Headers { get; set; }
} }
} }

View file

@ -1,8 +1,12 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Extensions;
@ -164,7 +168,7 @@ namespace Emby.Dlna.Eventing
try try
{ {
using (await _httpClient.SendAsync(options, "NOTIFY").ConfigureAwait(false)) using (await _httpClient.SendAsync(options, new HttpMethod("NOTIFY")).ConfigureAwait(false))
{ {
} }

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
namespace Emby.Dlna.Eventing namespace Emby.Dlna.Eventing
@ -13,6 +16,8 @@ namespace Emby.Dlna.Eventing
public long TriggerCount { get; set; } public long TriggerCount { get; set; }
public bool IsExpired => SubscriptionTime.AddSeconds(TimeoutSeconds) >= DateTime.UtcNow;
public void IncrementTriggerCount() public void IncrementTriggerCount()
{ {
if (TriggerCount == long.MaxValue) if (TriggerCount == long.MaxValue)
@ -22,7 +27,5 @@ namespace Emby.Dlna.Eventing
TriggerCount++; TriggerCount++;
} }
public bool IsExpired => SubscriptionTime.AddSeconds(TimeoutSeconds) >= DateTime.UtcNow;
} }
} }

View file

@ -1,3 +1,5 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
namespace Emby.Dlna namespace Emby.Dlna
{ {

View file

@ -1,3 +1,5 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
namespace Emby.Dlna namespace Emby.Dlna
{ {

View file

@ -1,3 +1,5 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
namespace Emby.Dlna namespace Emby.Dlna
{ {

View file

@ -1,3 +1,5 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
namespace Emby.Dlna namespace Emby.Dlna
{ {

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Emby.Dlna namespace Emby.Dlna

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Net.Sockets; using System.Net.Sockets;
using System.Globalization; using System.Globalization;

View file

@ -1,5 +1,9 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Xml;
using Emby.Dlna.Service; using Emby.Dlna.Service;
using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
@ -9,35 +13,33 @@ namespace Emby.Dlna.MediaReceiverRegistrar
{ {
public class ControlHandler : BaseControlHandler public class ControlHandler : BaseControlHandler
{ {
protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, IDictionary<string, string> methodParams)
{
if (string.Equals(methodName, "IsAuthorized", StringComparison.OrdinalIgnoreCase))
return HandleIsAuthorized();
if (string.Equals(methodName, "IsValidated", StringComparison.OrdinalIgnoreCase))
return HandleIsValidated();
throw new ResourceNotFoundException("Unexpected control request name: " + methodName);
}
private static IEnumerable<KeyValuePair<string, string>> HandleIsAuthorized()
{
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "Result", "1" }
};
}
private static IEnumerable<KeyValuePair<string, string>> HandleIsValidated()
{
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "Result", "1" }
};
}
public ControlHandler(IServerConfigurationManager config, ILogger logger) public ControlHandler(IServerConfigurationManager config, ILogger logger)
: base(config, logger) : base(config, logger)
{ {
} }
/// <inheritdoc />
protected override void WriteResult(string methodName, IDictionary<string, string> methodParams, XmlWriter xmlWriter)
{
if (string.Equals(methodName, "IsAuthorized", StringComparison.OrdinalIgnoreCase))
{
HandleIsAuthorized(xmlWriter);
return;
}
if (string.Equals(methodName, "IsValidated", StringComparison.OrdinalIgnoreCase))
{
HandleIsValidated(xmlWriter);
return;
}
throw new ResourceNotFoundException("Unexpected control request name: " + methodName);
}
private static void HandleIsAuthorized(XmlWriter xmlWriter)
=> xmlWriter.WriteElementString("Result", "1");
private static void HandleIsValidated(XmlWriter xmlWriter)
=> xmlWriter.WriteElementString("Result", "1");
} }
} }

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Threading.Tasks; using System.Threading.Tasks;
using Emby.Dlna.Service; using Emby.Dlna.Service;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
using Emby.Dlna.Common; using Emby.Dlna.Common;
using Emby.Dlna.Service; using Emby.Dlna.Service;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
using Emby.Dlna.Common; using Emby.Dlna.Common;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
@ -221,7 +224,7 @@ namespace Emby.Dlna.PlayTo
_logger.LogDebug("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).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value))
.ConfigureAwait(false); .ConfigureAwait(false);
IsMuted = mute; IsMuted = mute;
@ -251,7 +254,7 @@ namespace Emby.Dlna.PlayTo
// Remote control will perform better // Remote control will perform better
Volume = value; Volume = value;
await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value)) await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value))
.ConfigureAwait(false); .ConfigureAwait(false);
} }
@ -270,7 +273,7 @@ namespace Emby.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service"); throw new InvalidOperationException("Unable to find service");
} }
await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format("{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME")) await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format("{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME"))
.ConfigureAwait(false); .ConfigureAwait(false);
RestartTimer(true); RestartTimer(true);
@ -302,7 +305,7 @@ namespace Emby.Dlna.PlayTo
} }
var post = avCommands.BuildPost(command, service.ServiceType, url, dictionary); var post = avCommands.BuildPost(command, service.ServiceType, url, dictionary);
await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header: header) await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header: header)
.ConfigureAwait(false); .ConfigureAwait(false);
await Task.Delay(50).ConfigureAwait(false); await Task.Delay(50).ConfigureAwait(false);
@ -344,7 +347,7 @@ namespace Emby.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service"); throw new InvalidOperationException("Unable to find service");
} }
return new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)); return new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1));
} }
public async Task SetPlay(CancellationToken cancellationToken) public async Task SetPlay(CancellationToken cancellationToken)
@ -368,7 +371,7 @@ namespace Emby.Dlna.PlayTo
var service = GetAvTransportService(); var service = GetAvTransportService();
await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1))
.ConfigureAwait(false); .ConfigureAwait(false);
RestartTimer(true); RestartTimer(true);
@ -386,7 +389,7 @@ namespace Emby.Dlna.PlayTo
var service = GetAvTransportService(); var service = GetAvTransportService();
await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1))
.ConfigureAwait(false); .ConfigureAwait(false);
TransportState = TRANSPORTSTATE.PAUSED; TransportState = TRANSPORTSTATE.PAUSED;
@ -513,7 +516,7 @@ namespace Emby.Dlna.PlayTo
return; return;
} }
var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true) var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true)
.ConfigureAwait(false); .ConfigureAwait(false);
if (result == null || result.Document == null) if (result == null || result.Document == null)
@ -559,7 +562,7 @@ namespace Emby.Dlna.PlayTo
return; return;
} }
var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true) var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true)
.ConfigureAwait(false); .ConfigureAwait(false);
if (result == null || result.Document == null) if (result == null || result.Document == null)
@ -586,7 +589,7 @@ namespace Emby.Dlna.PlayTo
return null; return null;
} }
var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType), false) var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType), false)
.ConfigureAwait(false); .ConfigureAwait(false);
if (result == null || result.Document == null) if (result == null || result.Document == null)
@ -624,7 +627,7 @@ namespace Emby.Dlna.PlayTo
var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false) var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false)
.ConfigureAwait(false); .ConfigureAwait(false);
if (result == null || result.Document == null) if (result == null || result.Document == null)
@ -687,7 +690,7 @@ namespace Emby.Dlna.PlayTo
var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false) var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false)
.ConfigureAwait(false); .ConfigureAwait(false);
if (result == null || result.Document == null) if (result == null || result.Document == null)
@ -868,7 +871,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);
var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
@ -896,7 +899,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);
_logger.LogDebug("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);
@ -931,7 +934,7 @@ namespace Emby.Dlna.PlayTo
public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, CancellationToken cancellationToken) public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, CancellationToken cancellationToken)
{ {
var ssdpHttpClient = new SsdpHttpClient(httpClient, config); var ssdpHttpClient = new SsdpHttpClient(httpClient);
var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false); var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false);

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
using Emby.Dlna.Common; using Emby.Dlna.Common;
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
@ -21,7 +24,7 @@ using Microsoft.Extensions.Logging;
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo
{ {
class PlayToManager : IDisposable public class PlayToManager : IDisposable
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly ISessionManager _sessionManager; private readonly ISessionManager _sessionManager;
@ -64,10 +67,10 @@ namespace Emby.Dlna.PlayTo
public void Start() public void Start()
{ {
_deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered; _deviceDiscovery.DeviceDiscovered += OnDeviceDiscoveryDeviceDiscovered;
} }
async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<UpnpDeviceInfo> e) private async void OnDeviceDiscoveryDeviceDiscovered(object sender, GenericEventArgs<UpnpDeviceInfo> e)
{ {
if (_disposed) if (_disposed)
{ {
@ -231,7 +234,7 @@ namespace Emby.Dlna.PlayTo
public void Dispose() public void Dispose()
{ {
_deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered; _deviceDiscovery.DeviceDiscovered -= OnDeviceDiscoveryDeviceDiscovered;
try try
{ {

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;

View file

@ -1,13 +1,16 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Net.Http;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq; using System.Xml.Linq;
using Emby.Dlna.Common; using Emby.Dlna.Common;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo
{ {
@ -19,12 +22,10 @@ namespace Emby.Dlna.PlayTo
private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private readonly IHttpClient _httpClient; private readonly IHttpClient _httpClient;
private readonly IServerConfigurationManager _config;
public SsdpHttpClient(IHttpClient httpClient, IServerConfigurationManager config) public SsdpHttpClient(IHttpClient httpClient)
{ {
_httpClient = httpClient; _httpClient = httpClient;
_config = config;
} }
public async Task<XDocument> SendCommandAsync( public async Task<XDocument> SendCommandAsync(
@ -64,7 +65,9 @@ namespace Emby.Dlna.PlayTo
} }
if (!serviceUrl.StartsWith("/")) if (!serviceUrl.StartsWith("/"))
{
serviceUrl = "/" + serviceUrl; serviceUrl = "/" + serviceUrl;
}
return baseUrl + serviceUrl; return baseUrl + serviceUrl;
} }
@ -90,7 +93,7 @@ namespace Emby.Dlna.PlayTo
options.RequestHeaders["NT"] = "upnp:event"; options.RequestHeaders["NT"] = "upnp:event";
options.RequestHeaders["TIMEOUT"] = "Second-" + timeOut.ToString(_usCulture); options.RequestHeaders["TIMEOUT"] = "Second-" + timeOut.ToString(_usCulture);
using (await _httpClient.SendAsync(options, "SUBSCRIBE").ConfigureAwait(false)) using (await _httpClient.SendAsync(options, new HttpMethod("SUBSCRIBE")).ConfigureAwait(false))
{ {
} }
@ -110,7 +113,7 @@ namespace Emby.Dlna.PlayTo
options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName; options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
using (var response = await _httpClient.SendAsync(options, "GET").ConfigureAwait(false)) using (var response = await _httpClient.SendAsync(options, HttpMethod.Get).ConfigureAwait(false))
using (var stream = response.Content) using (var stream = response.Content)
using (var reader = new StreamReader(stream, Encoding.UTF8)) using (var reader = new StreamReader(stream, Encoding.UTF8))
{ {

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo
{ {
public enum TRANSPORTSTATE public enum TRANSPORTSTATE

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Xml.Linq; using System.Xml.Linq;
using Emby.Dlna.Ssdp; using Emby.Dlna.Ssdp;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Xml.Linq; using System.Xml.Linq;
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Linq; using System.Linq;
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
namespace Emby.Dlna.Profiles namespace Emby.Dlna.Profiles

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -65,8 +68,6 @@ namespace Emby.Dlna.Service
Logger.LogDebug("Received control request {0}", requestInfo.LocalName); Logger.LogDebug("Received control request {0}", requestInfo.LocalName);
var result = GetResult(requestInfo.LocalName, requestInfo.Headers);
var settings = new XmlWriterSettings var settings = new XmlWriterSettings
{ {
Encoding = Encoding.UTF8, Encoding = Encoding.UTF8,
@ -84,12 +85,9 @@ namespace Emby.Dlna.Service
writer.WriteStartElement("SOAP-ENV", "Body", NS_SOAPENV); writer.WriteStartElement("SOAP-ENV", "Body", NS_SOAPENV);
writer.WriteStartElement("u", requestInfo.LocalName + "Response", requestInfo.NamespaceURI); writer.WriteStartElement("u", requestInfo.LocalName + "Response", requestInfo.NamespaceURI);
foreach (var i in result)
{ WriteResult(requestInfo.LocalName, requestInfo.Headers, writer);
writer.WriteStartElement(i.Key);
writer.WriteString(i.Value);
writer.WriteFullEndElement();
}
writer.WriteFullEndElement(); writer.WriteFullEndElement();
writer.WriteFullEndElement(); writer.WriteFullEndElement();
@ -97,7 +95,7 @@ namespace Emby.Dlna.Service
writer.WriteEndDocument(); writer.WriteEndDocument();
} }
var xml = builder.ToString().Replace("xmlns:m=", "xmlns:u="); var xml = builder.ToString().Replace("xmlns:m=", "xmlns:u=", StringComparison.Ordinal);
var controlResponse = new ControlResponse var controlResponse = new ControlResponse
{ {
@ -218,7 +216,7 @@ namespace Emby.Dlna.Service
public Dictionary<string, string> Headers { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); public Dictionary<string, string> Headers { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
} }
protected abstract IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, IDictionary<string, string> methodParams); protected abstract void WriteResult(string methodName, IDictionary<string, string> methodParams, XmlWriter xmlWriter);
private void LogRequest(ControlRequest request) private void LogRequest(ControlRequest request)
{ {

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using Emby.Dlna.Eventing; using Emby.Dlna.Eventing;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Emby.Dlna.Common; using Emby.Dlna.Common;

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -9,16 +12,16 @@ using Rssdp.Infrastructure;
namespace Emby.Dlna.Ssdp namespace Emby.Dlna.Ssdp
{ {
public class DeviceDiscovery : IDeviceDiscovery public sealed class DeviceDiscovery : IDeviceDiscovery, IDisposable
{ {
private bool _disposed; private readonly object _syncLock = new object();
private readonly IServerConfigurationManager _config; private readonly IServerConfigurationManager _config;
private event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscoveredInternal;
private int _listenerCount; private int _listenerCount;
private object _syncLock = new object(); private bool _disposed;
private event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscoveredInternal;
/// <inheritdoc /> /// <inheritdoc />
public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered
@ -33,6 +36,7 @@ namespace Emby.Dlna.Ssdp
StartInternal(); StartInternal();
} }
remove remove
{ {
lock (_syncLock) lock (_syncLock)
@ -130,6 +134,7 @@ namespace Emby.Dlna.Ssdp
DeviceLeft?.Invoke(this, args); DeviceLeft?.Invoke(this, args);
} }
/// <inheritdoc />
public void Dispose() public void Dispose()
{ {
if (!_disposed) if (!_disposed)

View file

@ -1,3 +1,6 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
using System.Xml.Linq; using System.Xml.Linq;
namespace Emby.Dlna.Ssdp namespace Emby.Dlna.Ssdp

View file

@ -1533,7 +1533,7 @@ namespace Emby.Server.Implementations
string baseUrl = ServerConfigurationManager.Configuration.BaseUrl; string baseUrl = ServerConfigurationManager.Configuration.BaseUrl;
if (baseUrl.Length != 0) if (baseUrl.Length != 0)
{ {
url.Append('/').Append(baseUrl); url.Append(baseUrl);
} }
return url.ToString(); return url.ToString();

View file

@ -0,0 +1,96 @@
{
"DeviceOnlineWithName": "{0}-এর সাথে সংযুক্ত হয়েছে",
"DeviceOfflineWithName": "{0}-এর সাথে সংযোগ বিচ্ছিন্ন হয়েছে",
"Collections": "সংকলন",
"ChapterNameValue": "অধ্যায় {0}",
"Channels": "চ্যানেল",
"CameraImageUploadedFrom": "একটি নতুন ক্যামেরার চিত্র আপলোড করা হয়েছে {0} থেকে",
"Books": "বই",
"AuthenticationSucceededWithUserName": "{0} যাচাই সফল",
"Artists": "শিল্পী",
"Application": "অ্যাপ্লিকেশন",
"Albums": "অ্যালবামগুলো",
"HeaderFavoriteEpisodes": "প্রিব পর্বগুলো",
"HeaderFavoriteArtists": "প্রিয় শিল্পীরা",
"HeaderFavoriteAlbums": "প্রিয় এলবামগুলো",
"HeaderContinueWatching": "দেখতে থাকুন",
"HeaderCameraUploads": "ক্যামেরার আপলোডগুলো",
"HeaderAlbumArtists": "এলবামের শিল্পী",
"Genres": "ঘরানা",
"Folders": "ফোল্ডারগুলো",
"Favorites": "ফেভারিটগুলো",
"FailedLoginAttemptWithUserName": "{0} থেকে লগিন করতে ব্যর্থ",
"AppDeviceValues": "এপ: {0}, ডিভাইস: {0}",
"VersionNumber": "সংস্করণ {0}",
"ValueSpecialEpisodeName": "বিশেষ - {0}",
"ValueHasBeenAddedToLibrary": "আপনার লাইব্রেরিতে {0} যোগ করা হয়েছে",
"UserStoppedPlayingItemWithValues": "{2}তে {1} বাজানো শেষ করেছেন {0}",
"UserStartedPlayingItemWithValues": "{2}তে {1} বাজাচ্ছেন {0}",
"UserPolicyUpdatedWithName": "{0} এর জন্য ব্যবহার নীতি আপডেট করা হয়েছে",
"UserPasswordChangedWithName": "ব্যবহারকারী {0} এর পাসওয়ার্ড পরিবর্তিত হয়েছে",
"UserOnlineFromDevice": "{0}, {1} থেকে অনলাইন",
"UserOfflineFromDevice": "{0} {1} থেকে বিযুক্ত হয়ে গেছে",
"UserLockedOutWithName": "ব্যবহারকারী {0} ঢুকতে পারছে না",
"UserDownloadingItemWithValues": "{0}, {1} ডাউনলোড করছে",
"UserDeletedWithName": "ব্যবহারকারী {0}কে বাদ দেয়া হয়েছে",
"UserCreatedWithName": "ব্যবহারকারী {0} সৃষ্টি করা হয়েছে",
"User": "ব্যবহারকারী",
"TvShows": "টিভি শোগুলো",
"System": "সিস্টেম",
"Sync": "সিংক",
"SubtitlesDownloadedForItem": "{0} এর জন্য সাবটাইটেল ডাউনলোড করা হয়েছে",
"SubtitleDownloadFailureFromForItem": "{2} থেকে {1} এর জন্য সাবটাইটেল ডাউনলোড ব্যর্থ",
"StartupEmbyServerIsLoading": "জেলিফিন সার্ভার লোড হচ্ছে। দয়া করে একটু পরে আবার চেষ্টা করুন।",
"Songs": "গানগুলো",
"Shows": "টিভি পর্ব",
"ServerNameNeedsToBeRestarted": "{0} রিস্টার্ট করা প্রয়োজন",
"ScheduledTaskStartedWithName": "{0} শুরু হয়েছে",
"ScheduledTaskFailedWithName": "{0} ব্যর্থ",
"ProviderValue": "প্রদানকারী: {0}",
"PluginUpdatedWithName": "{0} আপডেট করা হয়েছে",
"PluginUninstalledWithName": "{0} বাদ দেয়া হয়েছে",
"PluginInstalledWithName": "{0} ইন্সটল করা হয়েছে",
"Plugin": "প্লাগিন",
"Playlists": "প্লেলিস্ট",
"Photos": "ছবিগুলো",
"NotificationOptionVideoPlaybackStopped": "ভিডিও চলা বন্ধ",
"NotificationOptionVideoPlayback": "ভিডিও চলা শুরু হয়েছে",
"NotificationOptionUserLockedOut": "ব্যবহারকারী ঢুকতে পারছে না",
"NotificationOptionTaskFailed": "পরিকল্পিত কাজটি ব্যর্থ",
"NotificationOptionServerRestartRequired": "সার্ভার রিস্টার্ট বাধ্যতামূলক",
"NotificationOptionPluginUpdateInstalled": "প্লাগিন আপডেট ইন্সটল করা হয়েছে",
"NotificationOptionPluginUninstalled": "প্লাগিন বাদ দেয়া হয়েছে",
"NotificationOptionPluginInstalled": "প্লাগিন ইন্সটল করা হয়েছে",
"NotificationOptionPluginError": "প্লাগিন ব্যর্থ",
"NotificationOptionNewLibraryContent": "নতুন কন্টেন্ট যোগ করা হয়েছে",
"NotificationOptionInstallationFailed": "ইন্সটল ব্যর্থ",
"NotificationOptionCameraImageUploaded": "ক্যামেরার ছবি আপলোড হয়েছে",
"NotificationOptionAudioPlaybackStopped": "গান বাজা বন্ধ হয়েছে",
"NotificationOptionAudioPlayback": "গান বাজা শুরু হয়েছে",
"NotificationOptionApplicationUpdateInstalled": "এপ্লিকেশনের আপডেট ইনস্টল করা হয়েছে",
"NotificationOptionApplicationUpdateAvailable": "এপ্লিকেশনের আপডেট রয়েছে",
"NewVersionIsAvailable": "জেলিফিন সার্ভারের একটি নতুন ভার্শন ডাউনলোডের জন্য তৈরী",
"NameSeasonUnknown": "সিজন অজানা",
"NameSeasonNumber": "সিজন {0}",
"NameInstallFailed": "{0} ইন্সটল ব্যর্থ",
"MusicVideos": "গানের ভিডিও",
"Music": "গান",
"Movies": "সিনেমা",
"MixedContent": "মিশ্র কন্টেন্ট",
"MessageServerConfigurationUpdated": "সার্ভারের কনফিগারেশন হালনাগাদ করা হয়েছে",
"HeaderRecordingGroups": "রেকর্ডিং গ্রুপ",
"MessageNamedServerConfigurationUpdatedWithValue": "সার্ভারের {0} কনফিগারেসন অংশ আপডেট করা হয়েছে",
"MessageApplicationUpdatedTo": "জেলিফিন সার্ভার {0} তে হালনাগাদ করা হয়েছে",
"MessageApplicationUpdated": "জেলিফিন সার্ভার হালনাগাদ করা হয়েছে",
"Latest": "একদম নতুন",
"LabelRunningTimeValue": "চলার সময়: {0}",
"LabelIpAddressValue": "আইপি ঠিকানা: {0}",
"ItemRemovedWithName": "{0} লাইব্রেরি থেকে বাদ দেয়া হয়েছে",
"ItemAddedWithName": "{0} লাইব্রেরিতে যোগ করা হয়েছে",
"Inherit": "থেকে পাওয়া",
"HomeVideos": "বাসার ভিডিও",
"HeaderNextUp": "এরপরে আসছে",
"HeaderLiveTV": "লাইভ টিভি",
"HeaderFavoriteSongs": "প্রিয় গানগুলো",
"HeaderFavoriteShows": "প্রিয় শোগুলো"
}

View file

@ -0,0 +1 @@
{}

View file

@ -1,6 +1,6 @@
{ {
"HeaderLiveTV": "Netti-TV", "HeaderLiveTV": "TV-lähetykset",
"NewVersionIsAvailable": "Uusi versio Jellyfin palvelimesta on ladattavissa", "NewVersionIsAvailable": "Uusi versio Jellyfin palvelimesta on ladattavissa.",
"NameSeasonUnknown": "Tuntematon Kausi", "NameSeasonUnknown": "Tuntematon Kausi",
"NameSeasonNumber": "Kausi {0}", "NameSeasonNumber": "Kausi {0}",
"NameInstallFailed": "{0} asennus epäonnistui", "NameInstallFailed": "{0} asennus epäonnistui",
@ -8,28 +8,28 @@
"Music": "Musiikki", "Music": "Musiikki",
"Movies": "Elokuvat", "Movies": "Elokuvat",
"MixedContent": "Sekoitettu sisältö", "MixedContent": "Sekoitettu sisältö",
"MessageServerConfigurationUpdated": "Palvelimen konfiguraatio on päivitetty", "MessageServerConfigurationUpdated": "Palvelimen asetukset on päivitetty",
"MessageNamedServerConfigurationUpdatedWithValue": "Palvelimen konfiguraatio-osa {0} on päivitetty", "MessageNamedServerConfigurationUpdatedWithValue": "Palvelimen asetusryhmä {0} on päivitetty",
"MessageApplicationUpdatedTo": "Jellyfin palvelin on päivitetty {0}", "MessageApplicationUpdatedTo": "Jellyfin palvelin on päivitetty versioon {0}",
"MessageApplicationUpdated": "Jellyfin palvelin on päivitetty", "MessageApplicationUpdated": "Jellyfin palvelin on päivitetty",
"Latest": "Viimeisin", "Latest": "Viimeisin",
"LabelRunningTimeValue": "Kesto: {0}", "LabelRunningTimeValue": "Toiston kesto: {0}",
"LabelIpAddressValue": "IP-osoite: {0}", "LabelIpAddressValue": "IP-osoite: {0}",
"ItemRemovedWithName": "{0} poistettiin kirjastosta", "ItemRemovedWithName": "{0} poistettiin kirjastosta",
"ItemAddedWithName": "{0} lisättiin kirjastoon", "ItemAddedWithName": "{0} lisättiin kirjastoon",
"Inherit": "Periä", "Inherit": "Periä",
"HomeVideos": "Kotivideot", "HomeVideos": "Kotivideot",
"HeaderRecordingGroups": "Äänitysryhmä", "HeaderRecordingGroups": "Äänitysryhmät",
"HeaderNextUp": "Seuraavaksi", "HeaderNextUp": "Seuraavaksi",
"HeaderFavoriteSongs": "Lempikappaleet", "HeaderFavoriteSongs": "Lempikappaleet",
"HeaderFavoriteShows": "Lempisarjat", "HeaderFavoriteShows": "Lempisarjat",
"HeaderFavoriteEpisodes": "Lempijaksot", "HeaderFavoriteEpisodes": "Lempijaksot",
"HeaderCameraUploads": "Kamerasta Ladatut", "HeaderCameraUploads": "Kamerasta lähetetyt",
"HeaderFavoriteArtists": "Lempiartistit", "HeaderFavoriteArtists": "Lempiartistit",
"HeaderFavoriteAlbums": "Lempialbumit", "HeaderFavoriteAlbums": "Lempialbumit",
"HeaderContinueWatching": "Jatka Katsomista", "HeaderContinueWatching": "Jatka katsomista",
"HeaderAlbumArtists": "Albumiartistit", "HeaderAlbumArtists": "Albumin artistit",
"Genres": "Genret", "Genres": "Tyylilaji",
"Folders": "Kansiot", "Folders": "Kansiot",
"Favorites": "Suosikit", "Favorites": "Suosikit",
"FailedLoginAttemptWithUserName": "Epäonnistunut kirjautumisyritys kohteesta {0}", "FailedLoginAttemptWithUserName": "Epäonnistunut kirjautumisyritys kohteesta {0}",
@ -44,5 +44,53 @@
"Artists": "Artistit", "Artists": "Artistit",
"Application": "Sovellus", "Application": "Sovellus",
"AppDeviceValues": "Sovellus: {0}, Laite: {1}", "AppDeviceValues": "Sovellus: {0}, Laite: {1}",
"Albums": "Albumit" "Albums": "Albumit",
"User": "Käyttäjä",
"System": "Järjestelmä",
"ScheduledTaskFailedWithName": "{0} epäonnistui",
"PluginUpdatedWithName": "{0} päivitetty",
"PluginInstalledWithName": "{0} asennettu",
"Photos": "Kuvat",
"ScheduledTaskStartedWithName": "{0} aloitettu",
"PluginUninstalledWithName": "{0} poistettu",
"Playlists": "Soittolistat",
"VersionNumber": "Versio {0}",
"ValueSpecialEpisodeName": "Erikois - {0}",
"ValueHasBeenAddedToLibrary": "{0} lisättiin mediakirjastoon",
"UserStoppedPlayingItemWithValues": "{0} toistaminen valmistui {1} laitteella {2}",
"UserStartedPlayingItemWithValues": "{0} toistaa {1} laitteella {2}",
"UserPolicyUpdatedWithName": "Käyttöoikeudet päivitetty käyttäjälle {0}",
"UserPasswordChangedWithName": "Salasana vaihdettu käyttäjälle {0}",
"UserOnlineFromDevice": "{0} on paikalla osoitteesta {1}",
"UserOfflineFromDevice": "{0} yhteys katkaistu {1}",
"UserLockedOutWithName": "Käyttäjä {0} kirjautui ulos",
"UserDownloadingItemWithValues": "{0} latautumassa {1}",
"UserDeletedWithName": "Poistettiin käyttäjä {0}",
"UserCreatedWithName": "Luotiin käyttäjä {0}",
"TvShows": "TV-Ohjelmat",
"Sync": "Synkronoi",
"SubtitlesDownloadedForItem": "Tekstitys ladattu {0}",
"SubtitleDownloadFailureFromForItem": "Tekstityksen lataaminen epäonnistui {0} - {1}",
"StartupEmbyServerIsLoading": "Jellyfin palvelin latautuu. Kokeile hetken kuluttua uudelleen.",
"Songs": "Kappaleet",
"Shows": "Ohjelmat",
"ServerNameNeedsToBeRestarted": "{0} vaatii uudelleenkäynnistyksen",
"ProviderValue": "Palveluntarjoaja: {0}",
"Plugin": "Laajennus",
"NotificationOptionVideoPlaybackStopped": "Videon toistaminen pysäytetty",
"NotificationOptionVideoPlayback": "Videon toistaminen aloitettu",
"NotificationOptionUserLockedOut": "Käyttäjä kirjautui ulos",
"NotificationOptionTaskFailed": "Ajastetun tehtävän ongelma",
"NotificationOptionServerRestartRequired": "Palvelimen uudelleenkäynnistys vaaditaan",
"NotificationOptionPluginUpdateInstalled": "Laajennuksen päivitys asennettu",
"NotificationOptionPluginUninstalled": "Laajennus poistettu",
"NotificationOptionPluginInstalled": "Laajennus asennettu",
"NotificationOptionPluginError": "Ongelma laajennuksessa",
"NotificationOptionNewLibraryContent": "Uusi sisältö lisätty",
"NotificationOptionInstallationFailed": "Asennusvirhe",
"NotificationOptionCameraImageUploaded": "Kameran kuva lisätty",
"NotificationOptionAudioPlaybackStopped": "Äänen toistaminen pysäytetty",
"NotificationOptionAudioPlayback": "Äänen toistaminen aloitettu",
"NotificationOptionApplicationUpdateInstalled": "Ohjelmistopäivitys asennettu",
"NotificationOptionApplicationUpdateAvailable": "Ohjelmistopäivitys saatavilla"
} }

View file

@ -1 +1,3 @@
{} {
"Albums": "Álbumes"
}

View file

@ -1,7 +1,7 @@
{ {
"Albums": "Albumok", "Albums": "Albumok",
"AppDeviceValues": "Program: {0}, Eszköz: {1}", "AppDeviceValues": "Program: {0}, Eszköz: {1}",
"Application": "Program", "Application": "Alkalmazás",
"Artists": "Előadók", "Artists": "Előadók",
"AuthenticationSucceededWithUserName": "{0} sikeresen azonosítva", "AuthenticationSucceededWithUserName": "{0} sikeresen azonosítva",
"Books": "Könyvek", "Books": "Könyvek",
@ -17,7 +17,7 @@
"Genres": "Műfajok", "Genres": "Műfajok",
"HeaderAlbumArtists": "Album előadók", "HeaderAlbumArtists": "Album előadók",
"HeaderCameraUploads": "Kamera feltöltések", "HeaderCameraUploads": "Kamera feltöltések",
"HeaderContinueWatching": "Folyamatban lévő filmek", "HeaderContinueWatching": "Megtekintés folytatása",
"HeaderFavoriteAlbums": "Kedvenc albumok", "HeaderFavoriteAlbums": "Kedvenc albumok",
"HeaderFavoriteArtists": "Kedvenc előadók", "HeaderFavoriteArtists": "Kedvenc előadók",
"HeaderFavoriteEpisodes": "Kedvenc epizódok", "HeaderFavoriteEpisodes": "Kedvenc epizódok",
@ -27,7 +27,7 @@
"HeaderNextUp": "Következik", "HeaderNextUp": "Következik",
"HeaderRecordingGroups": "Felvételi csoportok", "HeaderRecordingGroups": "Felvételi csoportok",
"HomeVideos": "Házi videók", "HomeVideos": "Házi videók",
"Inherit": "Inherit", "Inherit": "Öröklés",
"ItemAddedWithName": "{0} hozzáadva a könyvtárhoz", "ItemAddedWithName": "{0} hozzáadva a könyvtárhoz",
"ItemRemovedWithName": "{0} eltávolítva a könyvtárból", "ItemRemovedWithName": "{0} eltávolítva a könyvtárból",
"LabelIpAddressValue": "IP cím: {0}", "LabelIpAddressValue": "IP cím: {0}",
@ -42,7 +42,7 @@
"Music": "Zene", "Music": "Zene",
"MusicVideos": "Zenei videók", "MusicVideos": "Zenei videók",
"NameInstallFailed": "{0} sikertelen telepítés", "NameInstallFailed": "{0} sikertelen telepítés",
"NameSeasonNumber": "Évad {0}", "NameSeasonNumber": "{0}. évad",
"NameSeasonUnknown": "Ismeretlen évad", "NameSeasonUnknown": "Ismeretlen évad",
"NewVersionIsAvailable": "Letölthető a Jellyfin Szerver új verziója.", "NewVersionIsAvailable": "Letölthető a Jellyfin Szerver új verziója.",
"NotificationOptionApplicationUpdateAvailable": "Frissítés érhető el az alkalmazáshoz", "NotificationOptionApplicationUpdateAvailable": "Frissítés érhető el az alkalmazáshoz",

View file

@ -86,5 +86,10 @@
"FailedLoginAttemptWithUserName": "Percobaan login gagal dari {0}", "FailedLoginAttemptWithUserName": "Percobaan login gagal dari {0}",
"CameraImageUploadedFrom": "Sebuah gambar baru telah diunggah dari {0}", "CameraImageUploadedFrom": "Sebuah gambar baru telah diunggah dari {0}",
"DeviceOfflineWithName": "{0} telah terputus", "DeviceOfflineWithName": "{0} telah terputus",
"DeviceOnlineWithName": "{0} telah terhubung" "DeviceOnlineWithName": "{0} telah terhubung",
"NotificationOptionVideoPlaybackStopped": "Pemutaran video berhenti",
"NotificationOptionVideoPlayback": "Pemutaran video dimulai",
"NotificationOptionAudioPlaybackStopped": "Pemutaran audio berhenti",
"NotificationOptionAudioPlayback": "Pemutaran audio dimulai",
"MixedContent": "Konten campur"
} }

View file

@ -50,10 +50,10 @@
"NotificationOptionCameraImageUploaded": "相機相片已上傳", "NotificationOptionCameraImageUploaded": "相機相片已上傳",
"NotificationOptionInstallationFailed": "安裝失敗", "NotificationOptionInstallationFailed": "安裝失敗",
"NotificationOptionNewLibraryContent": "已新增新內容", "NotificationOptionNewLibraryContent": "已新增新內容",
"NotificationOptionPluginError": "外掛失敗", "NotificationOptionPluginError": "擴充元件安裝失敗",
"NotificationOptionPluginInstalled": "外掛已安裝", "NotificationOptionPluginInstalled": "擴充元件已安裝",
"NotificationOptionPluginUninstalled": "外掛已移除", "NotificationOptionPluginUninstalled": "擴充元件已移除",
"NotificationOptionPluginUpdateInstalled": "已更新外掛", "NotificationOptionPluginUpdateInstalled": "已更新擴充元件",
"NotificationOptionServerRestartRequired": "伺服器需要重新啟動", "NotificationOptionServerRestartRequired": "伺服器需要重新啟動",
"NotificationOptionTaskFailed": "排程任務失敗", "NotificationOptionTaskFailed": "排程任務失敗",
"NotificationOptionUserLockedOut": "使用者已鎖定", "NotificationOptionUserLockedOut": "使用者已鎖定",

View file

@ -1401,20 +1401,16 @@ namespace Emby.Server.Implementations.Session
user = _userManager.GetUserByName(request.Username); user = _userManager.GetUserByName(request.Username);
} }
if (user != null)
{
// TODO: Move this to userManager?
if (!string.IsNullOrEmpty(request.DeviceId)
&& !_deviceManager.CanAccessDevice(user, request.DeviceId))
{
throw new SecurityException("User is not allowed access from this device.");
}
}
if (user == null) if (user == null)
{ {
AuthenticationFailed?.Invoke(this, new GenericEventArgs<AuthenticationRequest>(request)); AuthenticationFailed?.Invoke(this, new GenericEventArgs<AuthenticationRequest>(request));
throw new SecurityException("Invalid user or password entered."); throw new SecurityException("Invalid username or password entered.");
}
if (!string.IsNullOrEmpty(request.DeviceId)
&& !_deviceManager.CanAccessDevice(user, request.DeviceId))
{
throw new SecurityException("User is not allowed access from this device.");
} }
if (enforcePassword) if (enforcePassword)
@ -1727,16 +1723,16 @@ namespace Emby.Server.Implementations.Session
/// <inheritdoc /> /// <inheritdoc />
public void ReportNowViewingItem(string sessionId, BaseItemDto item) public void ReportNowViewingItem(string sessionId, BaseItemDto item)
{ {
throw new NotImplementedException(); var session = GetSession(sessionId);
// var session = GetSession(sessionId); session.NowViewingItem = item;
// session.NowViewingItem = item;
} }
/// <inheritdoc /> /// <inheritdoc />
public void ReportTranscodingInfo(string deviceId, TranscodingInfo info) public void ReportTranscodingInfo(string deviceId, TranscodingInfo info)
{ {
var session = Sessions.FirstOrDefault(i => string.Equals(i.DeviceId, deviceId, StringComparison.Ordinal)); var session = Sessions.FirstOrDefault(i =>
string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase));
if (session != null) if (session != null)
{ {
@ -1752,8 +1748,11 @@ namespace Emby.Server.Implementations.Session
/// <inheritdoc /> /// <inheritdoc />
public SessionInfo GetSession(string deviceId, string client, string version) public SessionInfo GetSession(string deviceId, string client, string version)
=> Sessions.FirstOrDefault( {
i => string.Equals(i.DeviceId, deviceId, StringComparison.Ordinal) && string.Equals(i.Client, client, StringComparison.Ordinal)); return Sessions.FirstOrDefault(i =>
string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase)
&& string.Equals(i.Client, client, StringComparison.OrdinalIgnoreCase));
}
/// <inheritdoc /> /// <inheritdoc />
public SessionInfo GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion) public SessionInfo GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion)

Some files were not shown because too many files have changed in this diff Show more