From 5f5347aee3209383248a6055318ec8883291d406 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Fri, 9 Sep 2022 20:14:23 -0400
Subject: Add Lyrics API Endpoint
---
Jellyfin.Api/Controllers/UserLibraryController.cs | 49 +++++++++++++++++++++++
1 file changed, 49 insertions(+)
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index e45f9b58c..89fb56744 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -1,14 +1,18 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
+using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
+using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
+using Jellyfin.Api.Models.UserDtos;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
+using Kfstorm.LrcParser;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
@@ -381,5 +385,50 @@ namespace Jellyfin.Api.Controllers
return _userDataRepository.GetUserDataDto(item, user);
}
+
+ ///
+ /// Gets an item's lyrics.
+ ///
+ /// User id.
+ /// Item id.
+ /// Lyrics returned.
+ /// Something went wrong. No Lyrics will be returned.
+ /// An containing the intros to play.
+ [HttpGet("Users/{userId}/Items/{itemId}/Lyrics")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult> GetLyrics([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
+ {
+ var user = _userManager.GetUserById(userId);
+
+ if (user == null)
+ {
+ List lyricsList = new List
+ {
+ new Lyrics { Error = "User Not Found" }
+ };
+ return NotFound(new { Results = lyricsList.ToArray() });
+ }
+
+ var item = itemId.Equals(default)
+ ? _libraryManager.GetUserRootFolder()
+ : _libraryManager.GetItemById(itemId);
+
+ if (item == null)
+ {
+ List lyricsList = new List
+ {
+ new Lyrics { Error = "Requested Item Not Found" }
+ };
+ return NotFound(new { Results = lyricsList.ToArray() });
+ }
+
+ List result = ItemHelper.GetLyricData(item);
+ if (string.IsNullOrEmpty(result.ElementAt(0).Error))
+ {
+ return Ok(new { Results = result });
+ }
+
+ return NotFound(new { Results = result.ToArray() });
+ }
}
}
--
cgit v1.2.3
From 8b78802c0b42d9d55f5bd8c3f34a542d78903f75 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Fri, 9 Sep 2022 21:08:38 -0400
Subject: Update Jellyfin.Api/Controllers/UserLibraryController.cs
Co-authored-by: Cody Robibero
---
Jellyfin.Api/Controllers/UserLibraryController.cs | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index 89fb56744..42367940d 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -402,11 +402,7 @@ namespace Jellyfin.Api.Controllers
if (user == null)
{
- List lyricsList = new List
- {
- new Lyrics { Error = "User Not Found" }
- };
- return NotFound(new { Results = lyricsList.ToArray() });
+ return NotFound();
}
var item = itemId.Equals(default)
--
cgit v1.2.3
From 92715a74262fbf52f7071b45f5b61b7f057bb28e Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Fri, 9 Sep 2022 21:09:39 -0400
Subject: Update Jellyfin.Api/Controllers/UserLibraryController.cs
Co-authored-by: Cody Robibero
---
Jellyfin.Api/Controllers/UserLibraryController.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index 42367940d..a1b911a45 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -424,7 +424,7 @@ namespace Jellyfin.Api.Controllers
return Ok(new { Results = result });
}
- return NotFound(new { Results = result.ToArray() });
+ return NotFound();
}
}
}
--
cgit v1.2.3
From 0aa2780ea7b23aed31765550f707f7ea9fc0daf1 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Fri, 9 Sep 2022 21:15:57 -0400
Subject: Update Jellyfin.Api/Controllers/UserLibraryController.cs
Co-authored-by: Cody Robibero
---
Jellyfin.Api/Controllers/UserLibraryController.cs | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index a1b911a45..7830df9bc 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -411,11 +411,7 @@ namespace Jellyfin.Api.Controllers
if (item == null)
{
- List lyricsList = new List
- {
- new Lyrics { Error = "Requested Item Not Found" }
- };
- return NotFound(new { Results = lyricsList.ToArray() });
+ return NotFound();
}
List result = ItemHelper.GetLyricData(item);
--
cgit v1.2.3
From 2e260e5319b0b58290a1e30a28886c69d5a65325 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Sat, 10 Sep 2022 14:29:30 -0400
Subject: Updates based on review
---
Jellyfin.Api/Controllers/UserLibraryController.cs | 9 ++-
Jellyfin.Api/Helpers/ItemHelper.cs | 68 +++++++++++++---------
Jellyfin.Api/Jellyfin.Api.csproj | 13 +----
Jellyfin.Api/Libraries/LrcParser.dll | Bin 12288 -> 0 bytes
4 files changed, 46 insertions(+), 44 deletions(-)
delete mode 100644 Jellyfin.Api/Libraries/LrcParser.dll
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index 89fb56744..afd4013ed 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -12,7 +12,6 @@ using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.UserDtos;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
-using Kfstorm.LrcParser;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
@@ -422,13 +421,13 @@ namespace Jellyfin.Api.Controllers
return NotFound(new { Results = lyricsList.ToArray() });
}
- List result = ItemHelper.GetLyricData(item);
- if (string.IsNullOrEmpty(result.ElementAt(0).Error))
+ var result = ItemHelper.GetLyricData(item);
+ if (result is not null)
{
- return Ok(new { Results = result });
+ return Ok(result);
}
- return NotFound(new { Results = result.ToArray() });
+ return NotFound();
}
}
}
diff --git a/Jellyfin.Api/Helpers/ItemHelper.cs b/Jellyfin.Api/Helpers/ItemHelper.cs
index 43ef7aa09..c1b5ea6cc 100644
--- a/Jellyfin.Api/Helpers/ItemHelper.cs
+++ b/Jellyfin.Api/Helpers/ItemHelper.cs
@@ -1,19 +1,13 @@
using System;
using System.Collections.Generic;
+using System.Dynamic;
+using System.Globalization;
using System.IO;
-using System.Net.Http;
-using System.Threading.Tasks;
+using System.Linq;
using Jellyfin.Api.Models.UserDtos;
-using Kfstorm.LrcParser;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Devices;
-using MediaBrowser.Controller.Dlna;
+using LrcParser.Model;
+using LrcParser.Parser;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
namespace Jellyfin.Api.Helpers
{
@@ -27,7 +21,7 @@ namespace Jellyfin.Api.Helpers
///
/// Requested Item.
/// Collection of Lyrics.
- internal static List GetLyricData(BaseItem item)
+ internal static object? GetLyricData(BaseItem item)
{
List lyricsList = new List();
@@ -39,8 +33,7 @@ namespace Jellyfin.Api.Helpers
string txtFilePath = @Path.ChangeExtension(item.Path, "txt");
if (!System.IO.File.Exists(txtFilePath))
{
- lyricsList.Add(new Lyrics { Error = "Lyric File Not Found" });
- return lyricsList;
+ return null;
}
var lyricTextData = System.IO.File.ReadAllText(txtFilePath);
@@ -51,37 +44,58 @@ namespace Jellyfin.Api.Helpers
lyricsList.Add(new Lyrics { Text = lyricLine });
}
- return lyricsList;
+ return new { lyrics = lyricsList };
}
// Process LRC File
- ILrcFile lyricData;
+ Song lyricData;
+ List sortedLyricData = new List();
+ var metaData = new ExpandoObject() as IDictionary;
string lrcFileContent = System.IO.File.ReadAllText(lrcFilePath);
+
try
{
- lrcFileContent = lrcFileContent.Replace('<', '[');
- lrcFileContent = lrcFileContent.Replace('>', ']');
- lyricData = Kfstorm.LrcParser.LrcFile.FromText(lrcFileContent);
+ LyricParser lrcLyricParser = new LrcParser.Parser.Lrc.LrcParser();
+ lyricData = lrcLyricParser.Decode(lrcFileContent);
+ var _metaData = lyricData.Lyrics
+ .Where(x => x.TimeTags.Count == 0)
+ .Where(x => x.Text.StartsWith("[", StringComparison.Ordinal) && x.Text.EndsWith("]", StringComparison.Ordinal))
+ .Select(x => x.Text)
+ .ToList();
+
+ foreach (string dataRow in _metaData)
+ {
+ var data = dataRow.Split(":");
+
+ string newPropertyName = data[0].Replace("[", string.Empty, StringComparison.Ordinal);
+ string newPropertyValue = data[1].Replace("]", string.Empty, StringComparison.Ordinal);
+
+ metaData.Add(newPropertyName, newPropertyValue);
+ }
+
+ sortedLyricData = lyricData.Lyrics.Where(x => x.TimeTags.Count > 0).OrderBy(x => x.TimeTags.ToArray()[0].Value).ToList();
}
catch
{
- lyricsList.Add(new Lyrics { Error = "No Lyrics Data" });
- return lyricsList;
+ return null;
}
if (lyricData == null)
{
- lyricsList.Add(new Lyrics { Error = "No Lyrics Data" });
- return lyricsList;
+ return null;
}
- foreach (var lyricLine in lyricData.Lyrics)
+ for (int i = 0; i < sortedLyricData.Count; i++)
{
- double ticks = lyricLine.Timestamp.TotalSeconds * 10000000;
- lyricsList.Add(new Lyrics { Start = Math.Ceiling(ticks), Text = lyricLine.Content });
+ if (sortedLyricData[i].TimeTags.Count > 0)
+ {
+ var timeData = sortedLyricData[i].TimeTags.ToArray()[0].Value;
+ double ticks = Convert.ToDouble(timeData, new NumberFormatInfo()) * 10000;
+ lyricsList.Add(new Lyrics { Start = Math.Ceiling(ticks), Text = sortedLyricData[i].Text });
+ }
}
- return lyricsList;
+ return new { MetaData = metaData, lyrics = lyricsList };
}
}
}
diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj
index 1b78bb107..972387e02 100644
--- a/Jellyfin.Api/Jellyfin.Api.csproj
+++ b/Jellyfin.Api/Jellyfin.Api.csproj
@@ -17,6 +17,7 @@
+
@@ -46,16 +47,4 @@
-
-
- Libraries\LrcParser.dll
-
-
-
-
-
- Always
-
-
-
diff --git a/Jellyfin.Api/Libraries/LrcParser.dll b/Jellyfin.Api/Libraries/LrcParser.dll
deleted file mode 100644
index 46e4fb703..000000000
Binary files a/Jellyfin.Api/Libraries/LrcParser.dll and /dev/null differ
--
cgit v1.2.3
From d2e18547b16fa30684d7c9ceb8a117d5d9bcef56 Mon Sep 17 00:00:00 2001
From: Cody Robibero
Date: Sun, 11 Sep 2022 17:47:01 -0600
Subject: Require properly typed ActionResult (#8382)
---
Jellyfin.Api/BaseJellyfinApiController.cs | 37 ++++++++++++++++++++++
.../Controllers/ConfigurationController.cs | 1 -
Jellyfin.Api/Controllers/DlnaServerController.cs | 8 ++---
Jellyfin.Api/Controllers/MediaInfoController.cs | 1 -
Jellyfin.Api/Controllers/MoviesController.cs | 2 +-
Jellyfin.Api/Controllers/UserLibraryController.cs | 1 -
Jellyfin.Api/Controllers/UserViewsController.cs | 10 ++----
Jellyfin.Api/Results/OkResultOfT.cs | 21 ++++++++++++
8 files changed, 65 insertions(+), 16 deletions(-)
create mode 100644 Jellyfin.Api/Results/OkResultOfT.cs
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Jellyfin.Api/BaseJellyfinApiController.cs b/Jellyfin.Api/BaseJellyfinApiController.cs
index 59d6b7513..0c63d24b7 100644
--- a/Jellyfin.Api/BaseJellyfinApiController.cs
+++ b/Jellyfin.Api/BaseJellyfinApiController.cs
@@ -1,4 +1,6 @@
+using System.Collections.Generic;
using System.Net.Mime;
+using Jellyfin.Api.Results;
using Jellyfin.Extensions.Json;
using Microsoft.AspNetCore.Mvc;
@@ -15,5 +17,40 @@ namespace Jellyfin.Api
JsonDefaults.PascalCaseMediaType)]
public class BaseJellyfinApiController : ControllerBase
{
+ ///
+ /// Create a new .
+ ///
+ /// The value to return.
+ /// The type to return.
+ /// The .
+ protected ActionResult> Ok(List value)
+ => new OkResult>(value);
+
+ ///
+ /// Create a new .
+ ///
+ /// The value to return.
+ /// The type to return.
+ /// The .
+ protected ActionResult> Ok(IReadOnlyList value)
+ => new OkResult>(value);
+
+ ///
+ /// Create a new .
+ ///
+ /// The value to return.
+ /// The type to return.
+ /// The .
+ protected ActionResult> Ok(IEnumerable? value)
+ => new OkResult?>(value);
+
+ ///
+ /// Create a new .
+ ///
+ /// The value to return.
+ /// The type to return.
+ /// The .
+ protected ActionResult Ok(T value)
+ => new OkResult(value);
}
}
diff --git a/Jellyfin.Api/Controllers/ConfigurationController.cs b/Jellyfin.Api/Controllers/ConfigurationController.cs
index 464fadc06..bbe163312 100644
--- a/Jellyfin.Api/Controllers/ConfigurationController.cs
+++ b/Jellyfin.Api/Controllers/ConfigurationController.cs
@@ -2,7 +2,6 @@ using System;
using System.ComponentModel.DataAnnotations;
using System.Net.Mime;
using System.Text.Json;
-using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Models.ConfigurationDtos;
diff --git a/Jellyfin.Api/Controllers/DlnaServerController.cs b/Jellyfin.Api/Controllers/DlnaServerController.cs
index 401c0197a..8859d6020 100644
--- a/Jellyfin.Api/Controllers/DlnaServerController.cs
+++ b/Jellyfin.Api/Controllers/DlnaServerController.cs
@@ -54,7 +54,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status503ServiceUnavailable)]
[Produces(MediaTypeNames.Text.Xml)]
[ProducesFile(MediaTypeNames.Text.Xml)]
- public ActionResult GetDescriptionXml([FromRoute, Required] string serverId)
+ public ActionResult GetDescriptionXml([FromRoute, Required] string serverId)
{
var url = GetAbsoluteUri();
var serverAddress = url.Substring(0, url.IndexOf("/dlna/", StringComparison.OrdinalIgnoreCase));
@@ -77,7 +77,7 @@ namespace Jellyfin.Api.Controllers
[Produces(MediaTypeNames.Text.Xml)]
[ProducesFile(MediaTypeNames.Text.Xml)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
- public ActionResult GetContentDirectory([FromRoute, Required] string serverId)
+ public ActionResult GetContentDirectory([FromRoute, Required] string serverId)
{
return Ok(_contentDirectory.GetServiceXml());
}
@@ -97,7 +97,7 @@ namespace Jellyfin.Api.Controllers
[Produces(MediaTypeNames.Text.Xml)]
[ProducesFile(MediaTypeNames.Text.Xml)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
- public ActionResult GetMediaReceiverRegistrar([FromRoute, Required] string serverId)
+ public ActionResult GetMediaReceiverRegistrar([FromRoute, Required] string serverId)
{
return Ok(_mediaReceiverRegistrar.GetServiceXml());
}
@@ -117,7 +117,7 @@ namespace Jellyfin.Api.Controllers
[Produces(MediaTypeNames.Text.Xml)]
[ProducesFile(MediaTypeNames.Text.Xml)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")]
- public ActionResult GetConnectionManager([FromRoute, Required] string serverId)
+ public ActionResult GetConnectionManager([FromRoute, Required] string serverId)
{
return Ok(_connectionManager.GetServiceXml());
}
diff --git a/Jellyfin.Api/Controllers/MediaInfoController.cs b/Jellyfin.Api/Controllers/MediaInfoController.cs
index 75df18204..d2852ed01 100644
--- a/Jellyfin.Api/Controllers/MediaInfoController.cs
+++ b/Jellyfin.Api/Controllers/MediaInfoController.cs
@@ -12,7 +12,6 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.MediaInfo;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
diff --git a/Jellyfin.Api/Controllers/MoviesController.cs b/Jellyfin.Api/Controllers/MoviesController.cs
index 420dd9923..466944704 100644
--- a/Jellyfin.Api/Controllers/MoviesController.cs
+++ b/Jellyfin.Api/Controllers/MoviesController.cs
@@ -170,7 +170,7 @@ namespace Jellyfin.Api.Controllers
}
}
- return Ok(categories.OrderBy(i => i.RecommendationType));
+ return Ok(categories.OrderBy(i => i.RecommendationType).AsEnumerable());
}
private IEnumerable GetWithDirector(
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index e45f9b58c..1656a1e98 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -8,7 +8,6 @@ using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Enums;
-using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
diff --git a/Jellyfin.Api/Controllers/UserViewsController.cs b/Jellyfin.Api/Controllers/UserViewsController.cs
index 5cc8c906f..04732ccf2 100644
--- a/Jellyfin.Api/Controllers/UserViewsController.cs
+++ b/Jellyfin.Api/Controllers/UserViewsController.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
-using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.ModelBinders;
@@ -11,9 +10,7 @@ using Jellyfin.Api.Models.UserViewDtos;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.Querying;
using Microsoft.AspNetCore.Authorization;
@@ -32,7 +29,6 @@ namespace Jellyfin.Api.Controllers
private readonly IUserManager _userManager;
private readonly IUserViewManager _userViewManager;
private readonly IDtoService _dtoService;
- private readonly IAuthorizationContext _authContext;
private readonly ILibraryManager _libraryManager;
///
@@ -41,19 +37,16 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
public UserViewsController(
IUserManager userManager,
IUserViewManager userViewManager,
IDtoService dtoService,
- IAuthorizationContext authContext,
ILibraryManager libraryManager)
{
_userManager = userManager;
_userViewManager = userViewManager;
_dtoService = dtoService;
- _authContext = authContext;
_libraryManager = libraryManager;
}
@@ -138,7 +131,8 @@ namespace Jellyfin.Api.Controllers
Name = i.Name,
Id = i.Id.ToString("N", CultureInfo.InvariantCulture)
})
- .OrderBy(i => i.Name));
+ .OrderBy(i => i.Name)
+ .AsEnumerable());
}
}
}
diff --git a/Jellyfin.Api/Results/OkResultOfT.cs b/Jellyfin.Api/Results/OkResultOfT.cs
new file mode 100644
index 000000000..f60cbbcee
--- /dev/null
+++ b/Jellyfin.Api/Results/OkResultOfT.cs
@@ -0,0 +1,21 @@
+#pragma warning disable SA1649 // File name should match type name.
+
+using Microsoft.AspNetCore.Mvc;
+
+namespace Jellyfin.Api.Results;
+
+///
+/// Ok result with type specified.
+///
+/// The type to return.
+public class OkResult : OkObjectResult
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The value to return.
+ public OkResult(T value)
+ : base(value)
+ {
+ }
+}
--
cgit v1.2.3
From c71d6f2358ba8a5b1f80a2bef41b6f438c06d03c Mon Sep 17 00:00:00 2001
From: Zach Phelan
Date: Tue, 13 Sep 2022 16:40:47 -0600
Subject: Sort special features same as other spots, removing unnecssary
function
Added to contributors
---
CONTRIBUTORS.md | 1 +
Jellyfin.Api/Controllers/UserLibraryController.cs | 3 ++-
MediaBrowser.Controller/Entities/BaseItem.cs | 13 -------------
3 files changed, 3 insertions(+), 14 deletions(-)
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 98acd4449..8daaae4d9 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -148,6 +148,7 @@
- [xosdy](https://github.com/xosdy)
- [XVicarious](https://github.com/XVicarious)
- [YouKnowBlom](https://github.com/YouKnowBlom)
+ - [ZachPhelan](https://github.com/ZachPhelan)
- [KristupasSavickas](https://github.com/KristupasSavickas)
- [Pusta](https://github.com/pusta)
- [nielsvanvelzen](https://github.com/nielsvanvelzen)
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index 1656a1e98..940fa27a7 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -233,7 +233,8 @@ namespace Jellyfin.Api.Controllers
var dtoOptions = new DtoOptions().AddClientFields(Request);
return Ok(item
- .GetExtras(BaseItem.DisplayExtraTypes)
+ .GetExtras()
+ .Where(i => i.ExtraType.HasValue && BaseItem.DisplayExtraTypes.Contains(i.ExtraType.Value))
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)));
}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 5cee6ce40..988d0a534 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -2606,19 +2606,6 @@ namespace MediaBrowser.Controller.Entities
.OrderBy(i => i.SortName);
}
- ///
- /// Get all extras with specific types that are associated with this item.
- ///
- /// The types of extras to retrieve.
- /// An enumerable containing the extras.
- public IEnumerable GetExtras(IReadOnlyCollection extraTypes)
- {
- return ExtraIds
- .Select(LibraryManager.GetItemById)
- .Where(i => i != null)
- .Where(i => i.ExtraType.HasValue && extraTypes.Contains(i.ExtraType.Value));
- }
-
public virtual long GetRunTimeTicksForPlayState()
{
return RunTimeTicks ?? 0;
--
cgit v1.2.3
From c0dae0fef5255f27071b8dd84e8468a3e1ad29bf Mon Sep 17 00:00:00 2001
From: Jamie Introcaso
Date: Wed, 14 Sep 2022 20:39:26 -0400
Subject: Adds lyric providers to DI pipeline
This is adding those lyric providers to the DI pipeline along with a super simple implementation of how to use them in the controller method. Probably should be refactored into a lyric service of some sort that would have the providers injected into it.
---
Emby.Server.Implementations/ApplicationHost.cs | 3 +++
Jellyfin.Api/Controllers/UserLibraryController.cs | 19 ++++++++++++-------
2 files changed, 15 insertions(+), 7 deletions(-)
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 91a16c199..3e9c540e7 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -46,6 +46,7 @@ using Emby.Server.Implementations.SyncPlay;
using Emby.Server.Implementations.TV;
using Emby.Server.Implementations.Updates;
using Jellyfin.Api.Helpers;
+using Jellyfin.Api.Models.UserDtos;
using Jellyfin.MediaEncoding.Hls.Playlist;
using Jellyfin.Networking.Configuration;
using Jellyfin.Networking.Manager;
@@ -580,6 +581,8 @@ namespace Emby.Server.Implementations
serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService));
serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService));
serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService));
+ serviceCollection.AddTransient();
+ serviceCollection.AddTransient();
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index ed8a98d23..123c5e079 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -1,17 +1,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
-using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
-using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.UserDtos;
using Jellyfin.Data.Enums;
-using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
@@ -40,6 +37,7 @@ namespace Jellyfin.Api.Controllers
private readonly IDtoService _dtoService;
private readonly IUserViewManager _userViewManager;
private readonly IFileSystem _fileSystem;
+ private readonly IEnumerable _lyricProviders;
///
/// Initializes a new instance of the class.
@@ -50,13 +48,15 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
+ /// Collection of all registered interfaces.
public UserLibraryController(
IUserManager userManager,
IUserDataManager userDataRepository,
ILibraryManager libraryManager,
IDtoService dtoService,
IUserViewManager userViewManager,
- IFileSystem fileSystem)
+ IFileSystem fileSystem,
+ IEnumerable lyricProviders)
{
_userManager = userManager;
_userDataRepository = userDataRepository;
@@ -64,6 +64,7 @@ namespace Jellyfin.Api.Controllers
_dtoService = dtoService;
_userViewManager = userViewManager;
_fileSystem = fileSystem;
+ _lyricProviders = lyricProviders;
}
///
@@ -413,10 +414,14 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- var result = ItemHelper.GetLyricData(item);
- if (result is not null)
+ // Super nieve implementation. I would suggest building a lyric service of some sort and doing this there.
+ foreach (var provider in _lyricProviders)
{
- return Ok(result);
+ provider.Process(item);
+ if (provider.HasData)
+ {
+ return Ok(provider.Data);
+ }
}
return NotFound();
--
cgit v1.2.3
From d9be3874ba3842d5888c5cbbe583614ed990849e Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Thu, 15 Sep 2022 19:45:26 -0400
Subject: Auto stash before merge of "lyric-lrc-file-support" and
"origin/lyric-lrc-file-support"
---
Emby.Server.Implementations/ApplicationHost.cs | 2 +
Emby.Server.Implementations/Dto/DtoService.cs | 9 +-
Jellyfin.Api/Controllers/UserLibraryController.cs | 5 +-
Jellyfin.Api/Helpers/ItemHelper.cs | 106 -------------------
Jellyfin.Api/Jellyfin.Api.csproj | 1 -
Jellyfin.Api/Models/UserDtos/ILyricsProvider.cs | 34 ------
Jellyfin.Api/Models/UserDtos/LrcLyricsProvider.cs | 117 ---------------------
Jellyfin.Api/Models/UserDtos/Lyric.cs | 18 ----
Jellyfin.Api/Models/UserDtos/TxtLyricsProvider.cs | 81 --------------
MediaBrowser.Controller/Lyrics/ILyricsProvider.cs | 24 +++++
MediaBrowser.Controller/Lyrics/Lyric.cs | 18 ++++
MediaBrowser.Controller/Lyrics/LyricInfo.cs | 87 +++++++++++++++
MediaBrowser.Controller/Lyrics/LyricResponse.cs | 15 +++
MediaBrowser.Model/Dto/BaseItemDto.cs | 2 +-
MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs | 112 ++++++++++++++++++++
MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs | 74 +++++++++++++
.../MediaBrowser.Providers.csproj | 2 +
17 files changed, 345 insertions(+), 362 deletions(-)
delete mode 100644 Jellyfin.Api/Helpers/ItemHelper.cs
delete mode 100644 Jellyfin.Api/Models/UserDtos/ILyricsProvider.cs
delete mode 100644 Jellyfin.Api/Models/UserDtos/LrcLyricsProvider.cs
delete mode 100644 Jellyfin.Api/Models/UserDtos/Lyric.cs
delete mode 100644 Jellyfin.Api/Models/UserDtos/TxtLyricsProvider.cs
create mode 100644 MediaBrowser.Controller/Lyrics/ILyricsProvider.cs
create mode 100644 MediaBrowser.Controller/Lyrics/Lyric.cs
create mode 100644 MediaBrowser.Controller/Lyrics/LyricInfo.cs
create mode 100644 MediaBrowser.Controller/Lyrics/LyricResponse.cs
create mode 100644 MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs
create mode 100644 MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 3e9c540e7..5487e5e02 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -68,6 +68,7 @@ using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.Lyrics;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Notifications;
@@ -95,6 +96,7 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Providers.Chapters;
+using MediaBrowser.Providers.Lyric;
using MediaBrowser.Providers.Manager;
using MediaBrowser.Providers.Plugins.Tmdb;
using MediaBrowser.Providers.Subtitles;
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index 96717cff5..bed82a4bb 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -19,6 +19,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.Lyrics;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Controller.Providers;
@@ -51,6 +52,8 @@ namespace Emby.Server.Implementations.Dto
private readonly IMediaSourceManager _mediaSourceManager;
private readonly Lazy _livetvManagerFactory;
+ private readonly IEnumerable _lyricProviders;
+
public DtoService(
ILogger logger,
ILibraryManager libraryManager,
@@ -60,7 +63,8 @@ namespace Emby.Server.Implementations.Dto
IProviderManager providerManager,
IApplicationHost appHost,
IMediaSourceManager mediaSourceManager,
- Lazy livetvManagerFactory)
+ Lazy livetvManagerFactory,
+ IEnumerable lyricProviders)
{
_logger = logger;
_libraryManager = libraryManager;
@@ -71,6 +75,7 @@ namespace Emby.Server.Implementations.Dto
_appHost = appHost;
_mediaSourceManager = mediaSourceManager;
_livetvManagerFactory = livetvManagerFactory;
+ _lyricProviders = lyricProviders;
}
private ILiveTvManager LivetvManager => _livetvManagerFactory.Value;
@@ -142,7 +147,7 @@ namespace Emby.Server.Implementations.Dto
}
else if (item is Audio)
{
- dto.HasLocalLyricsFile = ItemHelper.HasLyricFile(item.Path);
+ dto.HasLyrics = MediaBrowser.Controller.Lyrics.LyricInfo.HasLyricFile(_lyricProviders, item.Path);
}
if (item is IItemByName itemByName
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index 123c5e079..3da78c116 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -13,6 +13,7 @@ using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Lyrics;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -414,8 +415,8 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- // Super nieve implementation. I would suggest building a lyric service of some sort and doing this there.
- foreach (var provider in _lyricProviders)
+ var result = MediaBrowser.Controller.Lyrics.LyricInfo.GetLyricData(_lyricProviders, item);
+ if (result is not null)
{
provider.Process(item);
if (provider.HasData)
diff --git a/Jellyfin.Api/Helpers/ItemHelper.cs b/Jellyfin.Api/Helpers/ItemHelper.cs
deleted file mode 100644
index 49bb8af8e..000000000
--- a/Jellyfin.Api/Helpers/ItemHelper.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Dynamic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using Jellyfin.Api.Models.UserDtos;
-using LrcParser.Model;
-using LrcParser.Parser;
-using MediaBrowser.Controller.Entities;
-
-namespace Jellyfin.Api.Helpers
-{
- ///
- /// Item helper.
- ///
- public static class ItemHelper
- {
- ///
- /// Opens lyrics file, converts to a List of Lyrics, and returns it.
- ///
- /// Requested Item.
- /// Collection of Lyrics.
- internal static object? GetLyricData(BaseItem item)
- {
- // Find all classes that implement ILyricsProvider Interface
- var foundLyricProviders = System.Reflection.Assembly.GetExecutingAssembly()
- .GetTypes()
- .Where(type => typeof(ILyricsProvider).IsAssignableFrom(type) && !type.IsInterface);
-
- if (!foundLyricProviders.Any())
- {
- return null;
- }
-
- foreach (var provider in foundLyricProviders)
- {
- ILyricsProvider? newProvider = Activator.CreateInstance(provider) as ILyricsProvider;
- if (newProvider is not null)
- {
- newProvider.Process(item);
- if (newProvider.HasData)
- {
- return newProvider.Data;
- }
- }
- }
-
- return null;
- }
-
- ///
- /// Checks if requested item has a matching lyric file.
- ///
- /// Path of requested item.
- /// True if item has a matching lyrics file.
- public static string? GetLyricFilePath(string itemPath)
- {
- // Find all classes that implement ILyricsProvider Interface
- var foundLyricProviders = System.Reflection.Assembly.GetExecutingAssembly()
- .GetTypes()
- .Where(type => typeof(ILyricsProvider).IsAssignableFrom(type) && !type.IsInterface);
-
- if (!foundLyricProviders.Any())
- {
- return null;
- }
-
- // Iterate over all found lyric providers
- foreach (var provider in foundLyricProviders)
- {
- ILyricsProvider? foundProvider = Activator.CreateInstance(provider) as ILyricsProvider;
- if (foundProvider?.FileExtensions is null)
- {
- continue;
- }
-
- if (foundProvider.FileExtensions.Any())
- {
- foreach (string lyricFileExtension in foundProvider.FileExtensions)
- {
- string lyricFilePath = @Path.ChangeExtension(itemPath, lyricFileExtension);
- if (System.IO.File.Exists(lyricFilePath))
- {
- return lyricFilePath;
- }
- }
- }
- }
-
- return null;
- }
-
-
- ///
- /// Checks if requested item has a matching local lyric file.
- ///
- /// Path of requested item.
- /// True if item has a matching lyrics file; otherwise false.
- public static bool HasLyricFile(string itemPath)
- {
- string? lyricFilePath = GetLyricFilePath(itemPath);
- return !string.IsNullOrEmpty(lyricFilePath);
- }
- }
-}
diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj
index 972387e02..894d87138 100644
--- a/Jellyfin.Api/Jellyfin.Api.csproj
+++ b/Jellyfin.Api/Jellyfin.Api.csproj
@@ -17,7 +17,6 @@
-
diff --git a/Jellyfin.Api/Models/UserDtos/ILyricsProvider.cs b/Jellyfin.Api/Models/UserDtos/ILyricsProvider.cs
deleted file mode 100644
index 37f1f5bbe..000000000
--- a/Jellyfin.Api/Models/UserDtos/ILyricsProvider.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System.Collections.ObjectModel;
-using MediaBrowser.Controller.Entities;
-
-namespace Jellyfin.Api.Models.UserDtos
-{
- ///
- /// Interface ILyricsProvider.
- ///
- public interface ILyricsProvider
- {
- ///
- /// Gets a value indicating the File Extenstions this provider works with.
- ///
- public Collection? FileExtensions { get; }
-
- ///
- /// Gets a value indicating whether Process() generated data.
- ///
- /// true if data generated; otherwise, false.
- bool HasData { get; }
-
- ///
- /// Gets Data object generated by Process() method.
- ///
- /// Object with data if no error occured; otherwise, null.
- object? Data { get; }
-
- ///
- /// Opens lyric file for [the specified item], and processes it for API return.
- ///
- /// The item to to process.
- void Process(BaseItem item);
- }
-}
diff --git a/Jellyfin.Api/Models/UserDtos/LrcLyricsProvider.cs b/Jellyfin.Api/Models/UserDtos/LrcLyricsProvider.cs
deleted file mode 100644
index 029acd6ca..000000000
--- a/Jellyfin.Api/Models/UserDtos/LrcLyricsProvider.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Dynamic;
-using System.Globalization;
-using System.Linq;
-using LrcParser.Model;
-using LrcParser.Parser;
-using MediaBrowser.Controller.Entities;
-
-namespace Jellyfin.Api.Models.UserDtos
-{
- ///
- /// LRC File Lyric Provider.
- ///
- public class LrcLyricsProvider : ILyricsProvider
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public LrcLyricsProvider()
- {
- FileExtensions = new Collection
- {
- "lrc"
- };
- }
-
- ///
- /// Gets a value indicating the File Extenstions this provider works with.
- ///
- public Collection? FileExtensions { get; }
-
- ///
- /// Gets or Sets a value indicating whether Process() generated data.
- ///
- /// true if data generated; otherwise, false.
- public bool HasData { get; set; }
-
- ///
- /// Gets or Sets Data object generated by Process() method.
- ///
- /// Object with data if no error occured; otherwise, null.
- public object? Data { get; set; }
-
- ///
- /// Opens lyric file for [the specified item], and processes it for API return.
- ///
- /// The item to to process.
- public void Process(BaseItem item)
- {
- string? lyricFilePath = Helpers.ItemHelper.GetLyricFilePath(item.Path);
-
- if (string.IsNullOrEmpty(lyricFilePath))
- {
- return;
- }
-
- List lyricsList = new List();
-
- List sortedLyricData = new List();
- var metaData = new ExpandoObject() as IDictionary;
- string lrcFileContent = System.IO.File.ReadAllText(lyricFilePath);
-
- try
- {
- // Parse and sort lyric rows
- LyricParser lrcLyricParser = new LrcParser.Parser.Lrc.LrcParser();
- Song lyricData = lrcLyricParser.Decode(lrcFileContent);
- sortedLyricData = lyricData.Lyrics.Where(x => x.TimeTags.Count > 0).OrderBy(x => x.TimeTags.ToArray()[0].Value).ToList();
-
- // Parse metadata rows
- var metaDataRows = lyricData.Lyrics
- .Where(x => x.TimeTags.Count == 0)
- .Where(x => x.Text.StartsWith("[", StringComparison.Ordinal) && x.Text.EndsWith("]", StringComparison.Ordinal))
- .Select(x => x.Text)
- .ToList();
-
- foreach (string metaDataRow in metaDataRows)
- {
- var metaDataField = metaDataRow.Split(":");
-
- string metaDataFieldName = metaDataField[0].Replace("[", string.Empty, StringComparison.Ordinal);
- string metaDataFieldValue = metaDataField[1].Replace("]", string.Empty, StringComparison.Ordinal);
-
- metaData.Add(metaDataFieldName, metaDataFieldValue);
- }
- }
- catch
- {
- return;
- }
-
- if (!sortedLyricData.Any())
- {
- return;
- }
-
- for (int i = 0; i < sortedLyricData.Count; i++)
- {
- var timeData = sortedLyricData[i].TimeTags.ToArray()[0].Value;
- double ticks = Convert.ToDouble(timeData, new NumberFormatInfo()) * 10000;
- lyricsList.Add(new Lyric { Start = Math.Ceiling(ticks), Text = sortedLyricData[i].Text });
- }
-
- this.HasData = true;
- if (metaData.Any())
- {
- this.Data = new { MetaData = metaData, lyrics = lyricsList };
- }
- else
- {
- this.Data = new { lyrics = lyricsList };
- }
- }
- }
-}
diff --git a/Jellyfin.Api/Models/UserDtos/Lyric.cs b/Jellyfin.Api/Models/UserDtos/Lyric.cs
deleted file mode 100644
index f83fc9839..000000000
--- a/Jellyfin.Api/Models/UserDtos/Lyric.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Jellyfin.Api.Models.UserDtos
-{
- ///
- /// Lyric dto.
- ///
- public class Lyric
- {
- ///
- /// Gets or sets the start time (ticks).
- ///
- public double? Start { get; set; }
-
- ///
- /// Gets or sets the text.
- ///
- public string Text { get; set; } = string.Empty;
- }
-}
diff --git a/Jellyfin.Api/Models/UserDtos/TxtLyricsProvider.cs b/Jellyfin.Api/Models/UserDtos/TxtLyricsProvider.cs
deleted file mode 100644
index 03cce1ffb..000000000
--- a/Jellyfin.Api/Models/UserDtos/TxtLyricsProvider.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Dynamic;
-using System.Globalization;
-using System.Linq;
-using LrcParser.Model;
-using LrcParser.Parser;
-using MediaBrowser.Controller.Entities;
-
-namespace Jellyfin.Api.Models.UserDtos
-{
- ///
- /// TXT File Lyric Provider.
- ///
- public class TxtLyricsProvider : ILyricsProvider
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public TxtLyricsProvider()
- {
- FileExtensions = new Collection
- {
- "lrc", "txt"
- };
- }
-
- ///
- /// Gets a value indicating the File Extenstions this provider works with.
- ///
- public Collection? FileExtensions { get; }
-
- ///
- /// Gets or Sets a value indicating whether Process() generated data.
- ///
- /// true if data generated; otherwise, false.
- public bool HasData { get; set; }
-
- ///
- /// Gets or Sets Data object generated by Process() method.
- ///
- /// Object with data if no error occured; otherwise, null.
- public object? Data { get; set; }
-
- ///
- /// Opens lyric file for [the specified item], and processes it for API return.
- ///
- /// The item to to process.
- public void Process(BaseItem item)
- {
- string? lyricFilePath = Helpers.ItemHelper.GetLyricFilePath(item.Path);
-
- if (string.IsNullOrEmpty(lyricFilePath))
- {
- return;
- }
-
- List lyricsList = new List();
-
- string lyricData = System.IO.File.ReadAllText(lyricFilePath);
-
- // Splitting on Environment.NewLine caused some new lines to be missed in Windows.
- char[] newLinedelims = new[] { '\r', '\n' };
- string[] lyricTextLines = lyricData.Split(newLinedelims, StringSplitOptions.RemoveEmptyEntries);
-
- if (!lyricTextLines.Any())
- {
- return;
- }
-
- foreach (string lyricLine in lyricTextLines)
- {
- lyricsList.Add(new Lyric { Text = lyricLine });
- }
-
- this.HasData = true;
- this.Data = new { lyrics = lyricsList };
- }
- }
-}
diff --git a/MediaBrowser.Controller/Lyrics/ILyricsProvider.cs b/MediaBrowser.Controller/Lyrics/ILyricsProvider.cs
new file mode 100644
index 000000000..bac32a398
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/ILyricsProvider.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+using MediaBrowser.Controller.Entities;
+
+namespace MediaBrowser.Controller.Lyrics
+{
+ ///
+ /// Interface ILyricsProvider.
+ ///
+ public interface ILyricsProvider
+ {
+ ///
+ /// Gets the supported media types for this provider.
+ ///
+ /// The supported media types.
+ IEnumerable SupportedMediaTypes { get; }
+
+ ///
+ /// Gets the lyrics.
+ ///
+ /// The item to to process.
+ /// Task{LyricResponse}.
+ LyricResponse? GetLyrics(BaseItem item);
+ }
+}
diff --git a/MediaBrowser.Controller/Lyrics/Lyric.cs b/MediaBrowser.Controller/Lyrics/Lyric.cs
new file mode 100644
index 000000000..d44546dd3
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/Lyric.cs
@@ -0,0 +1,18 @@
+namespace MediaBrowser.Controller.Lyrics
+{
+ ///
+ /// Lyric dto.
+ ///
+ public class Lyric
+ {
+ ///
+ /// Gets or sets the start time (ticks).
+ ///
+ public double? Start { get; set; }
+
+ ///
+ /// Gets or sets the text.
+ ///
+ public string Text { get; set; } = string.Empty;
+ }
+}
diff --git a/MediaBrowser.Controller/Lyrics/LyricInfo.cs b/MediaBrowser.Controller/Lyrics/LyricInfo.cs
new file mode 100644
index 000000000..83a10701a
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/LyricInfo.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Lyrics;
+using MediaBrowser.Controller.Net;
+using Microsoft.AspNetCore.Mvc;
+
+namespace MediaBrowser.Controller.Lyrics
+{
+ ///
+ /// Item helper.
+ ///
+ public class LyricInfo
+ {
+ ///
+ /// Opens lyrics file, converts to a List of Lyrics, and returns it.
+ ///
+ /// Collection of all registered interfaces.
+ /// Requested Item.
+ /// Collection of Lyrics.
+ public static LyricResponse? GetLyricData(IEnumerable lyricProviders, BaseItem item)
+ {
+
+ foreach (var provider in lyricProviders)
+ {
+ var result = provider.GetLyrics(item);
+ if (result is not null)
+ {
+ return result;
+ }
+ }
+
+ return new LyricResponse
+ {
+ Lyrics = new List
+ {
+ new Lyric { Start = 0, Text = "Test" }
+ }
+ };
+ }
+
+ ///
+ /// Checks if requested item has a matching lyric file.
+ ///
+ /// The current lyricProvider interface.
+ /// Path of requested item.
+ /// True if item has a matching lyrics file.
+ public static string? GetLyricFilePath(ILyricsProvider lyricProvider, string itemPath)
+ {
+ if (lyricProvider.SupportedMediaTypes.Any())
+ {
+ foreach (string lyricFileExtension in lyricProvider.SupportedMediaTypes)
+ {
+ string lyricFilePath = @Path.ChangeExtension(itemPath, lyricFileExtension);
+ if (System.IO.File.Exists(lyricFilePath))
+ {
+ return lyricFilePath;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Checks if requested item has a matching local lyric file.
+ ///
+ /// Collection of all registered interfaces.
+ /// Path of requested item.
+ /// True if item has a matching lyrics file; otherwise false.
+ public static bool HasLyricFile(IEnumerable lyricProviders, string itemPath)
+ {
+ foreach (var provider in lyricProviders)
+ {
+ if (GetLyricFilePath(provider, itemPath) is not null)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Lyrics/LyricResponse.cs b/MediaBrowser.Controller/Lyrics/LyricResponse.cs
new file mode 100644
index 000000000..e312638ec
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/LyricResponse.cs
@@ -0,0 +1,15 @@
+#nullable disable
+
+#pragma warning disable CS1591
+
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.Lyrics
+{
+ public class LyricResponse
+ {
+ public IDictionary MetaData { get; set; }
+
+ public IEnumerable Lyrics { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index b40a0210a..2a86fded2 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -76,7 +76,7 @@ namespace MediaBrowser.Model.Dto
public bool? CanDownload { get; set; }
- public bool? HasLocalLyricsFile { get; set; }
+ public bool? HasLyrics { get; set; }
public bool? HasSubtitles { get; set; }
diff --git a/MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs b/MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs
new file mode 100644
index 000000000..e30d56308
--- /dev/null
+++ b/MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Dynamic;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+using Jellyfin.Api.Helpers;
+using LrcParser.Model;
+using LrcParser.Parser;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Lyrics;
+
+namespace MediaBrowser.Providers.Lyric
+{
+ ///
+ /// LRC File Lyric Provider.
+ ///
+ public class LrcLyricsProvider : ILyricsProvider
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public LrcLyricsProvider()
+ {
+ SupportedMediaTypes = new Collection
+ {
+ "lrc"
+ };
+ }
+
+ ///
+ /// Gets a value indicating the File Extenstions this provider works with.
+ ///
+ public IEnumerable SupportedMediaTypes { get; }
+
+ ///
+ /// Gets or Sets Data object generated by Process() method.
+ ///
+ /// Object with data if no error occured; otherwise, null.
+ public object? Data { get; set; }
+
+ ///
+ /// Opens lyric file for [the specified item], and processes it for API return.
+ ///
+ /// The item to to process.
+ /// A representing the asynchronous operation.
+ public LyricResponse? GetLyrics(BaseItem item)
+ {
+ string? lyricFilePath = LyricInfo.GetLyricFilePath(this, item.Path);
+
+ if (string.IsNullOrEmpty(lyricFilePath))
+ {
+ return null;
+ }
+
+ List lyricsList = new List();
+
+ List sortedLyricData = new List();
+ var metaData = new ExpandoObject() as IDictionary;
+ string lrcFileContent = System.IO.File.ReadAllText(lyricFilePath);
+
+ try
+ {
+ // Parse and sort lyric rows
+ LyricParser lrcLyricParser = new LrcParser.Parser.Lrc.LrcParser();
+ Song lyricData = lrcLyricParser.Decode(lrcFileContent);
+ sortedLyricData = lyricData.Lyrics.Where(x => x.TimeTags.Count > 0).OrderBy(x => x.TimeTags.ToArray()[0].Value).ToList();
+
+ // Parse metadata rows
+ var metaDataRows = lyricData.Lyrics
+ .Where(x => x.TimeTags.Count == 0)
+ .Where(x => x.Text.StartsWith("[", StringComparison.Ordinal) && x.Text.EndsWith("]", StringComparison.Ordinal))
+ .Select(x => x.Text)
+ .ToList();
+
+ foreach (string metaDataRow in metaDataRows)
+ {
+ var metaDataField = metaDataRow.Split(":");
+
+ string metaDataFieldName = metaDataField[0].Replace("[", string.Empty, StringComparison.Ordinal);
+ string metaDataFieldValue = metaDataField[1].Replace("]", string.Empty, StringComparison.Ordinal);
+
+ metaData.Add(metaDataFieldName, metaDataFieldValue);
+ }
+ }
+ catch
+ {
+ return null;
+ }
+
+ if (!sortedLyricData.Any())
+ {
+ return null;
+ }
+
+ for (int i = 0; i < sortedLyricData.Count; i++)
+ {
+ var timeData = sortedLyricData[i].TimeTags.ToArray()[0].Value;
+ double ticks = Convert.ToDouble(timeData, new NumberFormatInfo()) * 10000;
+ lyricsList.Add(new MediaBrowser.Controller.Lyrics.Lyric { Start = Math.Ceiling(ticks), Text = sortedLyricData[i].Text });
+ }
+
+ if (metaData.Any())
+ {
+ return new LyricResponse { MetaData = metaData, Lyrics = lyricsList };
+ }
+
+ return new LyricResponse { Lyrics = lyricsList };
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs b/MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs
new file mode 100644
index 000000000..2a5da4e4d
--- /dev/null
+++ b/MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Threading.Tasks;
+using Jellyfin.Api.Helpers;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Lyrics;
+
+namespace MediaBrowser.Providers.Lyric
+{
+ ///
+ /// TXT File Lyric Provider.
+ ///
+ public class TxtLyricsProvider : ILyricsProvider
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TxtLyricsProvider()
+ {
+ SupportedMediaTypes = new Collection
+ {
+ "lrc", "txt"
+ };
+ }
+
+ ///
+ /// Gets a value indicating the File Extenstions this provider works with.
+ ///
+ public IEnumerable SupportedMediaTypes { get; }
+
+ ///
+ /// Gets or Sets Data object generated by Process() method.
+ ///
+ /// Object with data if no error occured; otherwise, null.
+ public object? Data { get; set; }
+
+ ///
+ /// Opens lyric file for [the specified item], and processes it for API return.
+ ///
+ /// The item to to process.
+ /// A representing the asynchronous operation.
+ public LyricResponse? GetLyrics(BaseItem item)
+ {
+ string? lyricFilePath = LyricInfo.GetLyricFilePath(this, item.Path);
+
+ if (string.IsNullOrEmpty(lyricFilePath))
+ {
+ return null;
+ }
+
+ List lyricsList = new List();
+
+ string lyricData = System.IO.File.ReadAllText(lyricFilePath);
+
+ // Splitting on Environment.NewLine caused some new lines to be missed in Windows.
+ char[] newLinedelims = new[] { '\r', '\n' };
+ string[] lyricTextLines = lyricData.Split(newLinedelims, StringSplitOptions.RemoveEmptyEntries);
+
+ if (!lyricTextLines.Any())
+ {
+ return null;
+ }
+
+ foreach (string lyricLine in lyricTextLines)
+ {
+ lyricsList.Add(new MediaBrowser.Controller.Lyrics.Lyric { Text = lyricLine });
+ }
+
+ return new LyricResponse { Lyrics = lyricsList };
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 9864db9ac..8514489f8 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -6,6 +6,7 @@
+
@@ -16,6 +17,7 @@
+
--
cgit v1.2.3
From f4fd908f8d7ffcdea6acaf75928f6c2960ed6338 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Thu, 15 Sep 2022 20:49:25 -0400
Subject: Create ILyricManager
---
Emby.Server.Implementations/ApplicationHost.cs | 4 +-
Emby.Server.Implementations/Dto/DtoService.cs | 8 +-
Jellyfin.Api/Controllers/UserLibraryController.cs | 16 ++-
MediaBrowser.Controller/Lyrics/ILyricManager.cs | 37 +++++++
MediaBrowser.Controller/Lyrics/ILyricProvider.cs | 29 ++++++
MediaBrowser.Controller/Lyrics/ILyricsProvider.cs | 24 -----
MediaBrowser.Controller/Lyrics/LyricInfo.cs | 50 +--------
MediaBrowser.Providers/Lyric/LrcLyricProvider.cs | 119 ++++++++++++++++++++++
MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs | 112 --------------------
MediaBrowser.Providers/Lyric/LyricManager.cs | 97 ++++++++++++++++++
MediaBrowser.Providers/Lyric/TxtLyricProvider.cs | 82 +++++++++++++++
MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs | 74 --------------
12 files changed, 378 insertions(+), 274 deletions(-)
create mode 100644 MediaBrowser.Controller/Lyrics/ILyricManager.cs
create mode 100644 MediaBrowser.Controller/Lyrics/ILyricProvider.cs
delete mode 100644 MediaBrowser.Controller/Lyrics/ILyricsProvider.cs
create mode 100644 MediaBrowser.Providers/Lyric/LrcLyricProvider.cs
delete mode 100644 MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs
create mode 100644 MediaBrowser.Providers/Lyric/LyricManager.cs
create mode 100644 MediaBrowser.Providers/Lyric/TxtLyricProvider.cs
delete mode 100644 MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 5487e5e02..409fc04b1 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -583,8 +583,6 @@ namespace Emby.Server.Implementations
serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService));
serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService));
serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService));
- serviceCollection.AddTransient();
- serviceCollection.AddTransient();
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
@@ -603,6 +601,7 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
+ serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
@@ -790,6 +789,7 @@ namespace Emby.Server.Implementations
Resolve().AddParts(GetExports(), GetExports(), GetExports());
Resolve().AddParts(GetExports());
+ Resolve().AddParts(GetExports());
Resolve().AddParts(GetExports());
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index bed82a4bb..6ab574c5c 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -52,7 +52,7 @@ namespace Emby.Server.Implementations.Dto
private readonly IMediaSourceManager _mediaSourceManager;
private readonly Lazy _livetvManagerFactory;
- private readonly IEnumerable _lyricProviders;
+ private readonly ILyricManager _lyricManager;
public DtoService(
ILogger logger,
@@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.Dto
IApplicationHost appHost,
IMediaSourceManager mediaSourceManager,
Lazy livetvManagerFactory,
- IEnumerable lyricProviders)
+ ILyricManager lyricManager)
{
_logger = logger;
_libraryManager = libraryManager;
@@ -75,7 +75,7 @@ namespace Emby.Server.Implementations.Dto
_appHost = appHost;
_mediaSourceManager = mediaSourceManager;
_livetvManagerFactory = livetvManagerFactory;
- _lyricProviders = lyricProviders;
+ _lyricManager = lyricManager;
}
private ILiveTvManager LivetvManager => _livetvManagerFactory.Value;
@@ -147,7 +147,7 @@ namespace Emby.Server.Implementations.Dto
}
else if (item is Audio)
{
- dto.HasLyrics = MediaBrowser.Controller.Lyrics.LyricInfo.HasLyricFile(_lyricProviders, item.Path);
+ dto.HasLyrics = _lyricManager.HasLyricFile(item);
}
if (item is IItemByName itemByName
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index 3da78c116..1421ab444 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -38,7 +38,7 @@ namespace Jellyfin.Api.Controllers
private readonly IDtoService _dtoService;
private readonly IUserViewManager _userViewManager;
private readonly IFileSystem _fileSystem;
- private readonly IEnumerable _lyricProviders;
+ private readonly ILyricManager _lyricManager;
///
/// Initializes a new instance of the class.
@@ -49,7 +49,7 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Collection of all registered interfaces.
+ /// Instance of the interface.
public UserLibraryController(
IUserManager userManager,
IUserDataManager userDataRepository,
@@ -57,7 +57,7 @@ namespace Jellyfin.Api.Controllers
IDtoService dtoService,
IUserViewManager userViewManager,
IFileSystem fileSystem,
- IEnumerable lyricProviders)
+ ILyricManager lyricManager)
{
_userManager = userManager;
_userDataRepository = userDataRepository;
@@ -65,7 +65,7 @@ namespace Jellyfin.Api.Controllers
_dtoService = dtoService;
_userViewManager = userViewManager;
_fileSystem = fileSystem;
- _lyricProviders = lyricProviders;
+ _lyricManager = lyricManager;
}
///
@@ -415,14 +415,10 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- var result = MediaBrowser.Controller.Lyrics.LyricInfo.GetLyricData(_lyricProviders, item);
+ var result = _lyricManager.GetLyric(item);
if (result is not null)
{
- provider.Process(item);
- if (provider.HasData)
- {
- return Ok(provider.Data);
- }
+ return Ok(result);
}
return NotFound();
diff --git a/MediaBrowser.Controller/Lyrics/ILyricManager.cs b/MediaBrowser.Controller/Lyrics/ILyricManager.cs
new file mode 100644
index 000000000..4fd11b9e0
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/ILyricManager.cs
@@ -0,0 +1,37 @@
+#nullable disable
+
+#pragma warning disable CS1591
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Providers;
+
+namespace MediaBrowser.Controller.Lyrics
+{
+ public interface ILyricManager
+ {
+ ///
+ /// Adds the parts.
+ ///
+ /// The lyric providers.
+ void AddParts(IEnumerable lyricProviders);
+
+ ///
+ /// Gets the lyrics.
+ ///
+ /// The media item.
+ /// Lyrics for passed item.
+ LyricResponse GetLyric(BaseItem item);
+
+ ///
+ /// Checks if requested item has a matching local lyric file.
+ ///
+ /// The media item.
+ /// True if item has a matching lyrics file; otherwise false.
+ bool HasLyricFile(BaseItem item);
+ }
+}
diff --git a/MediaBrowser.Controller/Lyrics/ILyricProvider.cs b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
new file mode 100644
index 000000000..691fed1fd
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+using MediaBrowser.Controller.Entities;
+
+namespace MediaBrowser.Controller.Lyrics
+{
+ ///
+ /// Interface ILyricsProvider.
+ ///
+ public interface ILyricProvider
+ {
+ ///
+ /// Gets a value indicating the provider name.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the supported media types for this provider.
+ ///
+ /// The supported media types.
+ IEnumerable SupportedMediaTypes { get; }
+
+ ///
+ /// Gets the lyrics.
+ ///
+ /// The item to to process.
+ /// Task{LyricResponse}.
+ LyricResponse? GetLyrics(BaseItem item);
+ }
+}
diff --git a/MediaBrowser.Controller/Lyrics/ILyricsProvider.cs b/MediaBrowser.Controller/Lyrics/ILyricsProvider.cs
deleted file mode 100644
index bac32a398..000000000
--- a/MediaBrowser.Controller/Lyrics/ILyricsProvider.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Collections.Generic;
-using MediaBrowser.Controller.Entities;
-
-namespace MediaBrowser.Controller.Lyrics
-{
- ///
- /// Interface ILyricsProvider.
- ///
- public interface ILyricsProvider
- {
- ///
- /// Gets the supported media types for this provider.
- ///
- /// The supported media types.
- IEnumerable SupportedMediaTypes { get; }
-
- ///
- /// Gets the lyrics.
- ///
- /// The item to to process.
- /// Task{LyricResponse}.
- LyricResponse? GetLyrics(BaseItem item);
- }
-}
diff --git a/MediaBrowser.Controller/Lyrics/LyricInfo.cs b/MediaBrowser.Controller/Lyrics/LyricInfo.cs
index 83a10701a..d44e14237 100644
--- a/MediaBrowser.Controller/Lyrics/LyricInfo.cs
+++ b/MediaBrowser.Controller/Lyrics/LyricInfo.cs
@@ -13,42 +13,15 @@ namespace MediaBrowser.Controller.Lyrics
///
/// Item helper.
///
- public class LyricInfo
+ public static class LyricInfo
{
- ///
- /// Opens lyrics file, converts to a List of Lyrics, and returns it.
- ///
- /// Collection of all registered interfaces.
- /// Requested Item.
- /// Collection of Lyrics.
- public static LyricResponse? GetLyricData(IEnumerable lyricProviders, BaseItem item)
- {
-
- foreach (var provider in lyricProviders)
- {
- var result = provider.GetLyrics(item);
- if (result is not null)
- {
- return result;
- }
- }
-
- return new LyricResponse
- {
- Lyrics = new List
- {
- new Lyric { Start = 0, Text = "Test" }
- }
- };
- }
-
///
/// Checks if requested item has a matching lyric file.
///
/// The current lyricProvider interface.
/// Path of requested item.
/// True if item has a matching lyrics file.
- public static string? GetLyricFilePath(ILyricsProvider lyricProvider, string itemPath)
+ public static string? GetLyricFilePath(ILyricProvider lyricProvider, string itemPath)
{
if (lyricProvider.SupportedMediaTypes.Any())
{
@@ -64,24 +37,5 @@ namespace MediaBrowser.Controller.Lyrics
return null;
}
-
- ///
- /// Checks if requested item has a matching local lyric file.
- ///
- /// Collection of all registered interfaces.
- /// Path of requested item.
- /// True if item has a matching lyrics file; otherwise false.
- public static bool HasLyricFile(IEnumerable lyricProviders, string itemPath)
- {
- foreach (var provider in lyricProviders)
- {
- if (GetLyricFilePath(provider, itemPath) is not null)
- {
- return true;
- }
- }
-
- return false;
- }
}
}
diff --git a/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs b/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs
new file mode 100644
index 000000000..18a85c93a
--- /dev/null
+++ b/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Dynamic;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+using Jellyfin.Api.Helpers;
+using LrcParser.Model;
+using LrcParser.Parser;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Lyrics;
+
+namespace MediaBrowser.Providers.Lyric
+{
+ ///
+ /// LRC File Lyric Provider.
+ ///
+ public class LrcLyricProvider : ILyricProvider
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public LrcLyricProvider()
+ {
+ Name = "LrcLyricProvider";
+
+ SupportedMediaTypes = new Collection
+ {
+ "lrc"
+ };
+ }
+
+ ///
+ /// Gets a value indicating the provider name.
+ ///
+ public string Name { get; }
+
+ ///
+ /// Gets a value indicating the File Extenstions this provider works with.
+ ///
+ public IEnumerable SupportedMediaTypes { get; }
+
+ ///
+ /// Gets or Sets Data object generated by Process() method.
+ ///
+ /// Object with data if no error occured; otherwise, null.
+ public object? Data { get; set; }
+
+ ///
+ /// Opens lyric file for [the specified item], and processes it for API return.
+ ///
+ /// The item to to process.
+ /// A representing the asynchronous operation.
+ public LyricResponse? GetLyrics(BaseItem item)
+ {
+ string? lyricFilePath = LyricInfo.GetLyricFilePath(this, item.Path);
+
+ if (string.IsNullOrEmpty(lyricFilePath))
+ {
+ return null;
+ }
+
+ List lyricsList = new List();
+
+ List sortedLyricData = new List();
+ var metaData = new ExpandoObject() as IDictionary;
+ string lrcFileContent = System.IO.File.ReadAllText(lyricFilePath);
+
+ try
+ {
+ // Parse and sort lyric rows
+ LyricParser lrcLyricParser = new LrcParser.Parser.Lrc.LrcParser();
+ Song lyricData = lrcLyricParser.Decode(lrcFileContent);
+ sortedLyricData = lyricData.Lyrics.Where(x => x.TimeTags.Count > 0).OrderBy(x => x.TimeTags.ToArray()[0].Value).ToList();
+
+ // Parse metadata rows
+ var metaDataRows = lyricData.Lyrics
+ .Where(x => x.TimeTags.Count == 0)
+ .Where(x => x.Text.StartsWith("[", StringComparison.Ordinal) && x.Text.EndsWith("]", StringComparison.Ordinal))
+ .Select(x => x.Text)
+ .ToList();
+
+ foreach (string metaDataRow in metaDataRows)
+ {
+ var metaDataField = metaDataRow.Split(":");
+
+ string metaDataFieldName = metaDataField[0].Replace("[", string.Empty, StringComparison.Ordinal);
+ string metaDataFieldValue = metaDataField[1].Replace("]", string.Empty, StringComparison.Ordinal);
+
+ metaData.Add(metaDataFieldName, metaDataFieldValue);
+ }
+ }
+ catch
+ {
+ return null;
+ }
+
+ if (!sortedLyricData.Any())
+ {
+ return null;
+ }
+
+ for (int i = 0; i < sortedLyricData.Count; i++)
+ {
+ var timeData = sortedLyricData[i].TimeTags.ToArray()[0].Value;
+ double ticks = Convert.ToDouble(timeData, new NumberFormatInfo()) * 10000;
+ lyricsList.Add(new MediaBrowser.Controller.Lyrics.Lyric { Start = Math.Ceiling(ticks), Text = sortedLyricData[i].Text });
+ }
+
+ if (metaData.Any())
+ {
+ return new LyricResponse { MetaData = metaData, Lyrics = lyricsList };
+ }
+
+ return new LyricResponse { Lyrics = lyricsList };
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs b/MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs
deleted file mode 100644
index e30d56308..000000000
--- a/MediaBrowser.Providers/Lyric/LrcLyricsProvider.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Dynamic;
-using System.Globalization;
-using System.Linq;
-using System.Threading.Tasks;
-using Jellyfin.Api.Helpers;
-using LrcParser.Model;
-using LrcParser.Parser;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Lyrics;
-
-namespace MediaBrowser.Providers.Lyric
-{
- ///
- /// LRC File Lyric Provider.
- ///
- public class LrcLyricsProvider : ILyricsProvider
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public LrcLyricsProvider()
- {
- SupportedMediaTypes = new Collection
- {
- "lrc"
- };
- }
-
- ///
- /// Gets a value indicating the File Extenstions this provider works with.
- ///
- public IEnumerable SupportedMediaTypes { get; }
-
- ///
- /// Gets or Sets Data object generated by Process() method.
- ///
- /// Object with data if no error occured; otherwise, null.
- public object? Data { get; set; }
-
- ///
- /// Opens lyric file for [the specified item], and processes it for API return.
- ///
- /// The item to to process.
- /// A representing the asynchronous operation.
- public LyricResponse? GetLyrics(BaseItem item)
- {
- string? lyricFilePath = LyricInfo.GetLyricFilePath(this, item.Path);
-
- if (string.IsNullOrEmpty(lyricFilePath))
- {
- return null;
- }
-
- List lyricsList = new List();
-
- List sortedLyricData = new List();
- var metaData = new ExpandoObject() as IDictionary;
- string lrcFileContent = System.IO.File.ReadAllText(lyricFilePath);
-
- try
- {
- // Parse and sort lyric rows
- LyricParser lrcLyricParser = new LrcParser.Parser.Lrc.LrcParser();
- Song lyricData = lrcLyricParser.Decode(lrcFileContent);
- sortedLyricData = lyricData.Lyrics.Where(x => x.TimeTags.Count > 0).OrderBy(x => x.TimeTags.ToArray()[0].Value).ToList();
-
- // Parse metadata rows
- var metaDataRows = lyricData.Lyrics
- .Where(x => x.TimeTags.Count == 0)
- .Where(x => x.Text.StartsWith("[", StringComparison.Ordinal) && x.Text.EndsWith("]", StringComparison.Ordinal))
- .Select(x => x.Text)
- .ToList();
-
- foreach (string metaDataRow in metaDataRows)
- {
- var metaDataField = metaDataRow.Split(":");
-
- string metaDataFieldName = metaDataField[0].Replace("[", string.Empty, StringComparison.Ordinal);
- string metaDataFieldValue = metaDataField[1].Replace("]", string.Empty, StringComparison.Ordinal);
-
- metaData.Add(metaDataFieldName, metaDataFieldValue);
- }
- }
- catch
- {
- return null;
- }
-
- if (!sortedLyricData.Any())
- {
- return null;
- }
-
- for (int i = 0; i < sortedLyricData.Count; i++)
- {
- var timeData = sortedLyricData[i].TimeTags.ToArray()[0].Value;
- double ticks = Convert.ToDouble(timeData, new NumberFormatInfo()) * 10000;
- lyricsList.Add(new MediaBrowser.Controller.Lyrics.Lyric { Start = Math.Ceiling(ticks), Text = sortedLyricData[i].Text });
- }
-
- if (metaData.Any())
- {
- return new LyricResponse { MetaData = metaData, Lyrics = lyricsList };
- }
-
- return new LyricResponse { Lyrics = lyricsList };
- }
- }
-}
diff --git a/MediaBrowser.Providers/Lyric/LyricManager.cs b/MediaBrowser.Providers/Lyric/LyricManager.cs
new file mode 100644
index 000000000..48572c63e
--- /dev/null
+++ b/MediaBrowser.Providers/Lyric/LyricManager.cs
@@ -0,0 +1,97 @@
+#nullable disable
+
+#pragma warning disable CS1591
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Jellyfin.Extensions;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Lyrics;
+using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Controller.Subtitles;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Providers;
+using Microsoft.Extensions.Logging;
+
+namespace MediaBrowser.Providers.Lyric
+{
+ public class LyricManager : ILyricManager
+ {
+ private readonly ILogger _logger;
+ private readonly IFileSystem _fileSystem;
+ private readonly ILibraryMonitor _monitor;
+ private readonly IMediaSourceManager _mediaSourceManager;
+ private readonly ILocalizationManager _localization;
+
+ private ILyricProvider[] _lyricProviders;
+
+ public LyricManager(
+ ILogger logger,
+ IFileSystem fileSystem,
+ ILibraryMonitor monitor,
+ IMediaSourceManager mediaSourceManager,
+ ILocalizationManager localizationManager)
+ {
+ _logger = logger;
+ _fileSystem = fileSystem;
+ _monitor = monitor;
+ _mediaSourceManager = mediaSourceManager;
+ _localization = localizationManager;
+ }
+
+ ///
+ public void AddParts(IEnumerable lyricProviders)
+ {
+ _lyricProviders = lyricProviders
+ .OrderBy(i => i is IHasOrder hasOrder ? hasOrder.Order : 0)
+ .ToArray();
+ }
+
+ ///
+ public LyricResponse GetLyric(BaseItem item)
+ {
+ foreach (ILyricProvider provider in _lyricProviders)
+ {
+ var results = provider.GetLyrics(item);
+ if (results is not null)
+ {
+ return results;
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ public bool HasLyricFile(BaseItem item)
+ {
+ foreach (ILyricProvider provider in _lyricProviders)
+ {
+ if (item is null)
+ {
+ continue;
+ }
+
+ if (LyricInfo.GetLyricFilePath(provider, item.Path) is not null)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs b/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs
new file mode 100644
index 000000000..939d8708b
--- /dev/null
+++ b/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using Jellyfin.Api.Helpers;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Lyrics;
+
+namespace MediaBrowser.Providers.Lyric
+{
+ ///
+ /// TXT File Lyric Provider.
+ ///
+ public class TxtLyricProvider : ILyricProvider
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TxtLyricProvider()
+ {
+ Name = "TxtLyricProvider";
+
+ SupportedMediaTypes = new Collection
+ {
+ "lrc", "txt"
+ };
+ }
+
+ ///
+ /// Gets a value indicating the provider name.
+ ///
+ public string Name { get; }
+
+ ///
+ /// Gets a value indicating the File Extenstions this provider works with.
+ ///
+ public IEnumerable SupportedMediaTypes { get; }
+
+ ///
+ /// Gets or Sets Data object generated by Process() method.
+ ///
+ /// Object with data if no error occured; otherwise, null.
+ public object? Data { get; set; }
+
+ ///
+ /// Opens lyric file for [the specified item], and processes it for API return.
+ ///
+ /// The item to to process.
+ /// A representing the asynchronous operation.
+ public LyricResponse? GetLyrics(BaseItem item)
+ {
+ string? lyricFilePath = LyricInfo.GetLyricFilePath(this, item.Path);
+
+ if (string.IsNullOrEmpty(lyricFilePath))
+ {
+ return null;
+ }
+
+ List lyricsList = new List();
+
+ string lyricData = System.IO.File.ReadAllText(lyricFilePath);
+
+ // Splitting on Environment.NewLine caused some new lines to be missed in Windows.
+ char[] newLinedelims = new[] { '\r', '\n' };
+ string[] lyricTextLines = lyricData.Split(newLinedelims, StringSplitOptions.RemoveEmptyEntries);
+
+ if (!lyricTextLines.Any())
+ {
+ return null;
+ }
+
+ foreach (string lyricLine in lyricTextLines)
+ {
+ lyricsList.Add(new MediaBrowser.Controller.Lyrics.Lyric { Text = lyricLine });
+ }
+
+ return new LyricResponse { Lyrics = lyricsList };
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs b/MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs
deleted file mode 100644
index 2a5da4e4d..000000000
--- a/MediaBrowser.Providers/Lyric/TxtLyricsProvider.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Threading.Tasks;
-using Jellyfin.Api.Helpers;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Lyrics;
-
-namespace MediaBrowser.Providers.Lyric
-{
- ///
- /// TXT File Lyric Provider.
- ///
- public class TxtLyricsProvider : ILyricsProvider
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public TxtLyricsProvider()
- {
- SupportedMediaTypes = new Collection
- {
- "lrc", "txt"
- };
- }
-
- ///
- /// Gets a value indicating the File Extenstions this provider works with.
- ///
- public IEnumerable SupportedMediaTypes { get; }
-
- ///
- /// Gets or Sets Data object generated by Process() method.
- ///
- /// Object with data if no error occured; otherwise, null.
- public object? Data { get; set; }
-
- ///
- /// Opens lyric file for [the specified item], and processes it for API return.
- ///
- /// The item to to process.
- /// A representing the asynchronous operation.
- public LyricResponse? GetLyrics(BaseItem item)
- {
- string? lyricFilePath = LyricInfo.GetLyricFilePath(this, item.Path);
-
- if (string.IsNullOrEmpty(lyricFilePath))
- {
- return null;
- }
-
- List lyricsList = new List();
-
- string lyricData = System.IO.File.ReadAllText(lyricFilePath);
-
- // Splitting on Environment.NewLine caused some new lines to be missed in Windows.
- char[] newLinedelims = new[] { '\r', '\n' };
- string[] lyricTextLines = lyricData.Split(newLinedelims, StringSplitOptions.RemoveEmptyEntries);
-
- if (!lyricTextLines.Any())
- {
- return null;
- }
-
- foreach (string lyricLine in lyricTextLines)
- {
- lyricsList.Add(new MediaBrowser.Controller.Lyrics.Lyric { Text = lyricLine });
- }
-
- return new LyricResponse { Lyrics = lyricsList };
- }
- }
-}
--
cgit v1.2.3
From f740d1b9f00d91bfad970f56abed67d8c8c16c9c Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Fri, 16 Sep 2022 20:52:40 -0400
Subject: Remove use of AddParts. Cleanup use of Lyric vs Lyrics.
---
Emby.Server.Implementations/ApplicationHost.cs | 2 +-
Jellyfin.Api/Controllers/UserLibraryController.cs | 6 +++---
Jellyfin.Server/CoreAppHost.cs | 6 ++++++
MediaBrowser.Controller/Lyrics/ILyricManager.cs | 18 ++--------------
MediaBrowser.Controller/Lyrics/ILyricProvider.cs | 4 ++--
MediaBrowser.Controller/Lyrics/Lyric.cs | 4 ++--
MediaBrowser.Controller/Lyrics/LyricInfo.cs | 8 +++----
MediaBrowser.Controller/Lyrics/LyricResponse.cs | 9 ++++++++
MediaBrowser.Providers/Lyric/LrcLyricProvider.cs | 24 ++++++++-------------
MediaBrowser.Providers/Lyric/LyricManager.cs | 16 +++++---------
MediaBrowser.Providers/Lyric/TxtLyricProvider.cs | 26 +++++++++--------------
11 files changed, 53 insertions(+), 70 deletions(-)
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 409fc04b1..5edc25952 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -789,7 +789,7 @@ namespace Emby.Server.Implementations
Resolve().AddParts(GetExports(), GetExports(), GetExports());
Resolve().AddParts(GetExports());
- Resolve().AddParts(GetExports());
+ //Resolve().AddParts(GetExports());
Resolve().AddParts(GetExports());
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index 1421ab444..2cb2e9328 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -394,10 +394,10 @@ namespace Jellyfin.Api.Controllers
/// Item id.
/// Lyrics returned.
/// Something went wrong. No Lyrics will be returned.
- /// An containing the intros to play.
+ /// An containing the item's lyrics.
[HttpGet("Users/{userId}/Items/{itemId}/Lyrics")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult> GetLyrics([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
+ public ActionResult> GetLyrics([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
{
var user = _userManager.GetUserById(userId);
@@ -415,7 +415,7 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- var result = _lyricManager.GetLyric(item);
+ var result = _lyricManager.GetLyrics(item);
if (result is not null)
{
return Ok(result);
diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs
index 67e50b92d..984711dc2 100644
--- a/Jellyfin.Server/CoreAppHost.cs
+++ b/Jellyfin.Server/CoreAppHost.cs
@@ -19,6 +19,7 @@ using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Lyrics;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.Activity;
@@ -95,6 +96,11 @@ namespace Jellyfin.Server
serviceCollection.AddScoped();
+ foreach (var type in GetExportTypes())
+ {
+ serviceCollection.AddSingleton(typeof(ILyricProvider), type);
+ }
+
base.RegisterServices(serviceCollection);
}
diff --git a/MediaBrowser.Controller/Lyrics/ILyricManager.cs b/MediaBrowser.Controller/Lyrics/ILyricManager.cs
index 4fd11b9e0..c0f78d177 100644
--- a/MediaBrowser.Controller/Lyrics/ILyricManager.cs
+++ b/MediaBrowser.Controller/Lyrics/ILyricManager.cs
@@ -1,37 +1,23 @@
-#nullable disable
-
#pragma warning disable CS1591
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Providers;
namespace MediaBrowser.Controller.Lyrics
{
public interface ILyricManager
{
- ///
- /// Adds the parts.
- ///
- /// The lyric providers.
- void AddParts(IEnumerable lyricProviders);
-
///
/// Gets the lyrics.
///
/// The media item.
/// Lyrics for passed item.
- LyricResponse GetLyric(BaseItem item);
+ LyricResponse GetLyrics(BaseItem item);
///
/// Checks if requested item has a matching local lyric file.
///
/// The media item.
- /// True if item has a matching lyrics file; otherwise false.
+ /// True if item has a matching lyric file; otherwise false.
bool HasLyricFile(BaseItem item);
}
}
diff --git a/MediaBrowser.Controller/Lyrics/ILyricProvider.cs b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
index 691fed1fd..5e677ab26 100644
--- a/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
+++ b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
@@ -22,8 +22,8 @@ namespace MediaBrowser.Controller.Lyrics
///
/// Gets the lyrics.
///
- /// The item to to process.
- /// Task{LyricResponse}.
+ /// The media item.
+ /// If found, returns lyrics for passed item; otherwise, null.
LyricResponse? GetLyrics(BaseItem item);
}
}
diff --git a/MediaBrowser.Controller/Lyrics/Lyric.cs b/MediaBrowser.Controller/Lyrics/Lyric.cs
index d44546dd3..56a0a8a72 100644
--- a/MediaBrowser.Controller/Lyrics/Lyric.cs
+++ b/MediaBrowser.Controller/Lyrics/Lyric.cs
@@ -1,12 +1,12 @@
namespace MediaBrowser.Controller.Lyrics
{
///
- /// Lyric dto.
+ /// Lyric model.
///
public class Lyric
{
///
- /// Gets or sets the start time (ticks).
+ /// Gets or sets the start time in ticks.
///
public double? Start { get; set; }
diff --git a/MediaBrowser.Controller/Lyrics/LyricInfo.cs b/MediaBrowser.Controller/Lyrics/LyricInfo.cs
index d44e14237..018f296b1 100644
--- a/MediaBrowser.Controller/Lyrics/LyricInfo.cs
+++ b/MediaBrowser.Controller/Lyrics/LyricInfo.cs
@@ -11,16 +11,16 @@ using Microsoft.AspNetCore.Mvc;
namespace MediaBrowser.Controller.Lyrics
{
///
- /// Item helper.
+ /// Lyric helper methods.
///
public static class LyricInfo
{
///
- /// Checks if requested item has a matching lyric file.
+ /// Gets matching lyric file for a requested item.
///
- /// The current lyricProvider interface.
+ /// The lyricProvider interface to use.
/// Path of requested item.
- /// True if item has a matching lyrics file.
+ /// Lyric file path if passed lyric provider's supported media type is found; otherwise, null.
public static string? GetLyricFilePath(ILyricProvider lyricProvider, string itemPath)
{
if (lyricProvider.SupportedMediaTypes.Any())
diff --git a/MediaBrowser.Controller/Lyrics/LyricResponse.cs b/MediaBrowser.Controller/Lyrics/LyricResponse.cs
index e312638ec..498eb873c 100644
--- a/MediaBrowser.Controller/Lyrics/LyricResponse.cs
+++ b/MediaBrowser.Controller/Lyrics/LyricResponse.cs
@@ -6,10 +6,19 @@ using System.Collections.Generic;
namespace MediaBrowser.Controller.Lyrics
{
+ ///
+ /// LyricResponse model.
+ ///
public class LyricResponse
{
+ ///
+ /// Gets or sets MetaData.
+ ///
public IDictionary MetaData { get; set; }
+ ///
+ /// Gets or sets Lyrics.
+ ///
public IEnumerable Lyrics { get; set; }
}
}
diff --git a/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs b/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs
index 18a85c93a..10db10ac6 100644
--- a/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs
+++ b/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs
@@ -14,7 +14,7 @@ using MediaBrowser.Controller.Lyrics;
namespace MediaBrowser.Providers.Lyric
{
///
- /// LRC File Lyric Provider.
+ /// LRC Lyric Provider.
///
public class LrcLyricProvider : ILyricProvider
{
@@ -37,21 +37,15 @@ namespace MediaBrowser.Providers.Lyric
public string Name { get; }
///
- /// Gets a value indicating the File Extenstions this provider works with.
+ /// Gets a value indicating the File Extenstions this provider supports.
///
public IEnumerable SupportedMediaTypes { get; }
///
- /// Gets or Sets Data object generated by Process() method.
- ///
- /// Object with data if no error occured; otherwise, null.
- public object? Data { get; set; }
-
- ///
- /// Opens lyric file for [the specified item], and processes it for API return.
+ /// Opens lyric file for the requested item, and processes it for API return.
///
/// The item to to process.
- /// A representing the asynchronous operation.
+ /// If provider can determine lyrics, returns a with or without metadata; otherwise, null.
public LyricResponse? GetLyrics(BaseItem item)
{
string? lyricFilePath = LyricInfo.GetLyricFilePath(this, item.Path);
@@ -61,9 +55,9 @@ namespace MediaBrowser.Providers.Lyric
return null;
}
- List lyricsList = new List();
-
+ List lyricList = new List();
List sortedLyricData = new List();
+
var metaData = new ExpandoObject() as IDictionary;
string lrcFileContent = System.IO.File.ReadAllText(lyricFilePath);
@@ -105,15 +99,15 @@ namespace MediaBrowser.Providers.Lyric
{
var timeData = sortedLyricData[i].TimeTags.ToArray()[0].Value;
double ticks = Convert.ToDouble(timeData, new NumberFormatInfo()) * 10000;
- lyricsList.Add(new MediaBrowser.Controller.Lyrics.Lyric { Start = Math.Ceiling(ticks), Text = sortedLyricData[i].Text });
+ lyricList.Add(new Controller.Lyrics.Lyric { Start = Math.Ceiling(ticks), Text = sortedLyricData[i].Text });
}
if (metaData.Any())
{
- return new LyricResponse { MetaData = metaData, Lyrics = lyricsList };
+ return new LyricResponse { MetaData = metaData, Lyrics = lyricList };
}
- return new LyricResponse { Lyrics = lyricsList };
+ return new LyricResponse { Lyrics = lyricList };
}
}
}
diff --git a/MediaBrowser.Providers/Lyric/LyricManager.cs b/MediaBrowser.Providers/Lyric/LyricManager.cs
index 48572c63e..698da4686 100644
--- a/MediaBrowser.Providers/Lyric/LyricManager.cs
+++ b/MediaBrowser.Providers/Lyric/LyricManager.cs
@@ -36,32 +36,26 @@ namespace MediaBrowser.Providers.Lyric
private readonly IMediaSourceManager _mediaSourceManager;
private readonly ILocalizationManager _localization;
- private ILyricProvider[] _lyricProviders;
+ private IEnumerable _lyricProviders;
public LyricManager(
ILogger logger,
IFileSystem fileSystem,
ILibraryMonitor monitor,
IMediaSourceManager mediaSourceManager,
- ILocalizationManager localizationManager)
+ ILocalizationManager localizationManager,
+ IEnumerable lyricProviders)
{
_logger = logger;
_fileSystem = fileSystem;
_monitor = monitor;
_mediaSourceManager = mediaSourceManager;
_localization = localizationManager;
+ _lyricProviders = lyricProviders;
}
///
- public void AddParts(IEnumerable lyricProviders)
- {
- _lyricProviders = lyricProviders
- .OrderBy(i => i is IHasOrder hasOrder ? hasOrder.Order : 0)
- .ToArray();
- }
-
- ///
- public LyricResponse GetLyric(BaseItem item)
+ public LyricResponse GetLyrics(BaseItem item)
{
foreach (ILyricProvider provider in _lyricProviders)
{
diff --git a/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs b/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs
index 939d8708b..aa222ed97 100644
--- a/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs
+++ b/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs
@@ -11,7 +11,7 @@ using MediaBrowser.Controller.Lyrics;
namespace MediaBrowser.Providers.Lyric
{
///
- /// TXT File Lyric Provider.
+ /// TXT Lyric Provider.
///
public class TxtLyricProvider : ILyricProvider
{
@@ -34,21 +34,15 @@ namespace MediaBrowser.Providers.Lyric
public string Name { get; }
///
- /// Gets a value indicating the File Extenstions this provider works with.
+ /// Gets a value indicating the File Extenstions this provider supports.
///
public IEnumerable SupportedMediaTypes { get; }
///
- /// Gets or Sets Data object generated by Process() method.
- ///
- /// Object with data if no error occured; otherwise, null.
- public object? Data { get; set; }
-
- ///
- /// Opens lyric file for [the specified item], and processes it for API return.
+ /// Opens lyric file for the requested item, and processes it for API return.
///
/// The item to to process.
- /// A representing the asynchronous operation.
+ /// If provider can determine lyrics, returns a ; otherwise, null.
public LyricResponse? GetLyrics(BaseItem item)
{
string? lyricFilePath = LyricInfo.GetLyricFilePath(this, item.Path);
@@ -58,25 +52,25 @@ namespace MediaBrowser.Providers.Lyric
return null;
}
- List lyricsList = new List();
+ List lyricList = new List();
string lyricData = System.IO.File.ReadAllText(lyricFilePath);
// Splitting on Environment.NewLine caused some new lines to be missed in Windows.
- char[] newLinedelims = new[] { '\r', '\n' };
- string[] lyricTextLines = lyricData.Split(newLinedelims, StringSplitOptions.RemoveEmptyEntries);
+ char[] newLineDelims = new[] { '\r', '\n' };
+ string[] lyricTextLines = lyricData.Split(newLineDelims, StringSplitOptions.RemoveEmptyEntries);
if (!lyricTextLines.Any())
{
return null;
}
- foreach (string lyricLine in lyricTextLines)
+ foreach (string lyricTextLine in lyricTextLines)
{
- lyricsList.Add(new MediaBrowser.Controller.Lyrics.Lyric { Text = lyricLine });
+ lyricList.Add(new Controller.Lyrics.Lyric { Text = lyricTextLine });
}
- return new LyricResponse { Lyrics = lyricsList };
+ return new LyricResponse { Lyrics = lyricList };
}
}
}
--
cgit v1.2.3
From 8912f618f59c1e798e406b8ed7fed4504e2c2de3 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Fri, 16 Sep 2022 21:11:28 -0400
Subject: Change API GetLyrics return type
---
Jellyfin.Api/Controllers/UserLibraryController.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index 2cb2e9328..df91a8efc 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -397,7 +397,7 @@ namespace Jellyfin.Api.Controllers
/// An containing the item's lyrics.
[HttpGet("Users/{userId}/Items/{itemId}/Lyrics")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult> GetLyrics([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
+ public ActionResult GetLyrics([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
{
var user = _userManager.GetUserById(userId);
--
cgit v1.2.3
From a50bdb47709be0412b3abb2729f8c657b5d0c779 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Thu, 22 Sep 2022 08:13:53 -0400
Subject: Use async functions
---
Jellyfin.Api/Controllers/UserLibraryController.cs | 4 ++--
MediaBrowser.Controller/Lyrics/ILyricManager.cs | 5 +++--
MediaBrowser.Controller/Lyrics/ILyricProvider.cs | 5 +++--
MediaBrowser.Providers/Lyric/LrcLyricProvider.cs | 23 +++++++++++++++++------
MediaBrowser.Providers/Lyric/LyricManager.cs | 5 +++--
MediaBrowser.Providers/Lyric/TxtLyricProvider.cs | 5 +++--
6 files changed, 31 insertions(+), 16 deletions(-)
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index df91a8efc..682a6e832 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -397,7 +397,7 @@ namespace Jellyfin.Api.Controllers
/// An containing the item's lyrics.
[HttpGet("Users/{userId}/Items/{itemId}/Lyrics")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult GetLyrics([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
+ public async Task> GetLyrics([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
{
var user = _userManager.GetUserById(userId);
@@ -415,7 +415,7 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- var result = _lyricManager.GetLyrics(item);
+ var result = await _lyricManager.GetLyrics(item).ConfigureAwait(false);
if (result is not null)
{
return Ok(result);
diff --git a/MediaBrowser.Controller/Lyrics/ILyricManager.cs b/MediaBrowser.Controller/Lyrics/ILyricManager.cs
index 5920bcc62..bb93e1e4c 100644
--- a/MediaBrowser.Controller/Lyrics/ILyricManager.cs
+++ b/MediaBrowser.Controller/Lyrics/ILyricManager.cs
@@ -1,3 +1,4 @@
+using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Lyrics;
@@ -11,8 +12,8 @@ public interface ILyricManager
/// Gets the lyrics.
///
/// The media item.
- /// Lyrics for passed item.
- LyricResponse? GetLyrics(BaseItem item);
+ /// A task representing found lyrics the passed item.
+ Task GetLyrics(BaseItem item);
///
/// Checks if requested item has a matching local lyric file.
diff --git a/MediaBrowser.Controller/Lyrics/ILyricProvider.cs b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
index c5b625226..2a04c6152 100644
--- a/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
+++ b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Resolvers;
@@ -30,6 +31,6 @@ public interface ILyricProvider
/// Gets the lyrics.
///
/// The media item.
- /// If found, returns lyrics for passed item; otherwise, null.
- LyricResponse? GetLyrics(BaseItem item);
+ /// A task representing found lyrics.
+ Task GetLyrics(BaseItem item);
}
diff --git a/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs b/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs
index 1dbe5958e..d06db3afc 100644
--- a/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs
+++ b/MediaBrowser.Providers/Lyric/LrcLyricProvider.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using LrcParser.Model;
using LrcParser.Parser;
using MediaBrowser.Controller.Entities;
@@ -50,7 +51,7 @@ public class LrcLyricProvider : ILyricProvider
///
/// The item to to process.
/// If provider can determine lyrics, returns a with or without metadata; otherwise, null.
- public LyricResponse? GetLyrics(BaseItem item)
+ public async Task GetLyrics(BaseItem item)
{
string? lyricFilePath = this.GetLyricFilePath(item.Path);
@@ -60,7 +61,7 @@ public class LrcLyricProvider : ILyricProvider
}
var fileMetaData = new Dictionary(StringComparer.OrdinalIgnoreCase);
- string lrcFileContent = File.ReadAllText(lyricFilePath);
+ string lrcFileContent = await Task.FromResult(File.ReadAllText(lyricFilePath)).ConfigureAwait(false);
Song lyricData;
@@ -94,15 +95,15 @@ public class LrcLyricProvider : ILyricProvider
// Remove square bracket before field name, and after field value
// Example 1: [au: 1hitsong]
// Example 2: [ar: Calabrese]
- var metaDataFieldNameSpan = metaDataRow.AsSpan(1, index - 1).Trim();
- var metaDataFieldValueSpan = metaDataRow.AsSpan(index + 1, metaDataRow.Length - index - 2).Trim();
+ var metaDataFieldName = GetMetadataFieldName(metaDataRow, index);
+ var metaDataFieldValue = GetMetadataValue(metaDataRow, index);
- if (metaDataFieldValueSpan.IsEmpty || metaDataFieldValueSpan.IsEmpty)
+ if (string.IsNullOrEmpty(metaDataFieldName) || string.IsNullOrEmpty(metaDataFieldValue))
{
continue;
}
- fileMetaData[metaDataFieldNameSpan.ToString()] = metaDataFieldValueSpan.ToString();
+ fileMetaData[metaDataFieldName.ToString()] = metaDataFieldValue.ToString();
}
if (sortedLyricData.Count == 0)
@@ -197,4 +198,14 @@ public class LrcLyricProvider : ILyricProvider
return lyricMetadata;
}
+
+ private static string GetMetadataFieldName(string metaDataRow, int index)
+ {
+ return metaDataRow.AsSpan(1, index - 1).Trim().ToString();
+ }
+
+ private static string GetMetadataValue(string metaDataRow, int index)
+ {
+ return metaDataRow.AsSpan(index + 1, metaDataRow.Length - index - 2).Trim().ToString();
+ }
}
diff --git a/MediaBrowser.Providers/Lyric/LyricManager.cs b/MediaBrowser.Providers/Lyric/LyricManager.cs
index 336b324a7..f9547e0f0 100644
--- a/MediaBrowser.Providers/Lyric/LyricManager.cs
+++ b/MediaBrowser.Providers/Lyric/LyricManager.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Lyrics;
@@ -22,11 +23,11 @@ public class LyricManager : ILyricManager
}
///
- public LyricResponse? GetLyrics(BaseItem item)
+ public async Task GetLyrics(BaseItem item)
{
foreach (ILyricProvider provider in _lyricProviders)
{
- var results = provider.GetLyrics(item);
+ var results = await provider.GetLyrics(item).ConfigureAwait(false);
if (results is not null)
{
return results;
diff --git a/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs b/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs
index bce881054..9df4ec83e 100644
--- a/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs
+++ b/MediaBrowser.Providers/Lyric/TxtLyricProvider.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Lyrics;
using MediaBrowser.Controller.Resolvers;
@@ -29,7 +30,7 @@ public class TxtLyricProvider : ILyricProvider
///
/// The item to to process.
/// If provider can determine lyrics, returns a ; otherwise, null.
- public LyricResponse? GetLyrics(BaseItem item)
+ public async Task GetLyrics(BaseItem item)
{
string? lyricFilePath = this.GetLyricFilePath(item.Path);
@@ -38,7 +39,7 @@ public class TxtLyricProvider : ILyricProvider
return null;
}
- string[] lyricTextLines = File.ReadAllLines(lyricFilePath);
+ string[] lyricTextLines = await Task.FromResult(File.ReadAllLines(lyricFilePath)).ConfigureAwait(false);
if (lyricTextLines.Length == 0)
{
--
cgit v1.2.3
From 5dc30c6a6d8af9a758fd730c9da69c13847c21c3 Mon Sep 17 00:00:00 2001
From: cvium
Date: Thu, 6 Oct 2022 13:57:47 +0200
Subject: fix: use HttpContext and ClaimsPrincipal instead of
IAuthorizationContext
---
Emby.Server.Implementations/ApplicationHost.cs | 2 -
.../HttpServer/Security/SessionContext.cs | 59 ---------------
.../Session/SessionWebSocketListener.cs | 16 ++--
Jellyfin.Api/Auth/BaseAuthorizationHandler.cs | 9 ++-
.../SyncPlayAccessPolicy/SyncPlayAccessHandler.cs | 9 ++-
Jellyfin.Api/Controllers/ArtistsController.cs | 6 +-
Jellyfin.Api/Controllers/ClientLogController.cs | 7 +-
Jellyfin.Api/Controllers/CollectionController.cs | 11 +--
Jellyfin.Api/Controllers/DynamicHlsController.cs | 14 +---
Jellyfin.Api/Controllers/GenresController.cs | 4 +-
Jellyfin.Api/Controllers/ImageController.cs | 19 ++---
Jellyfin.Api/Controllers/InstantMixController.cs | 14 ++--
Jellyfin.Api/Controllers/ItemsController.cs | 20 ++---
Jellyfin.Api/Controllers/LibraryController.cs | 37 ++++-----
Jellyfin.Api/Controllers/LiveTvController.cs | 39 ++++++----
Jellyfin.Api/Controllers/MediaInfoController.cs | 16 ++--
Jellyfin.Api/Controllers/MoviesController.cs | 2 +-
Jellyfin.Api/Controllers/MusicGenresController.cs | 4 +-
Jellyfin.Api/Controllers/PersonsController.cs | 4 +-
Jellyfin.Api/Controllers/PlaylistsController.cs | 2 +-
Jellyfin.Api/Controllers/PlaystateController.cs | 28 +++----
Jellyfin.Api/Controllers/QuickConnectController.cs | 7 +-
Jellyfin.Api/Controllers/SessionController.cs | 33 ++++----
Jellyfin.Api/Controllers/StudiosController.cs | 4 +-
Jellyfin.Api/Controllers/SubtitleController.cs | 8 +-
Jellyfin.Api/Controllers/SuggestionsController.cs | 2 +-
Jellyfin.Api/Controllers/SyncPlayController.cs | 54 ++++++-------
Jellyfin.Api/Controllers/TvShowsController.cs | 8 +-
.../Controllers/UniversalAudioController.cs | 14 +---
Jellyfin.Api/Controllers/UserController.cs | 23 +++---
Jellyfin.Api/Controllers/UserLibraryController.cs | 12 +--
Jellyfin.Api/Controllers/UserViewsController.cs | 2 +-
Jellyfin.Api/Controllers/VideosController.cs | 9 +--
Jellyfin.Api/Controllers/YearsController.cs | 4 +-
.../Extensions/ClaimsPrincipalExtensions.cs | 81 ++++++++++++++++++++
Jellyfin.Api/Extensions/DtoExtensions.cs | 8 +-
Jellyfin.Api/Helpers/AudioHelper.cs | 8 +-
Jellyfin.Api/Helpers/ClaimHelpers.cs | 88 ----------------------
Jellyfin.Api/Helpers/DynamicHlsHelper.cs | 11 +--
Jellyfin.Api/Helpers/MediaInfoHelper.cs | 33 ++++----
Jellyfin.Api/Helpers/RequestHelpers.cs | 48 +++++++-----
Jellyfin.Api/Helpers/StreamingHelpers.cs | 15 ++--
Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 17 +++--
MediaBrowser.Controller/Net/ISessionContext.cs | 20 -----
44 files changed, 335 insertions(+), 496 deletions(-)
delete mode 100644 Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
create mode 100644 Jellyfin.Api/Extensions/ClaimsPrincipalExtensions.cs
delete mode 100644 Jellyfin.Api/Helpers/ClaimHelpers.cs
delete mode 100644 MediaBrowser.Controller/Net/ISessionContext.cs
(limited to 'Jellyfin.Api/Controllers/UserLibraryController.cs')
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 91a16c199..9a9de1059 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -630,8 +630,6 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton();
- serviceCollection.AddScoped();
-
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
diff --git a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
deleted file mode 100644
index e0d20e210..000000000
--- a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-#pragma warning disable CS1591
-
-using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Controller.Session;
-using Microsoft.AspNetCore.Http;
-
-namespace Emby.Server.Implementations.HttpServer.Security
-{
- public class SessionContext : ISessionContext
- {
- private readonly IUserManager _userManager;
- private readonly ISessionManager _sessionManager;
- private readonly IAuthorizationContext _authContext;
-
- public SessionContext(IUserManager userManager, IAuthorizationContext authContext, ISessionManager sessionManager)
- {
- _userManager = userManager;
- _authContext = authContext;
- _sessionManager = sessionManager;
- }
-
- public async Task GetSession(HttpContext requestContext)
- {
- var authorization = await _authContext.GetAuthorizationInfo(requestContext).ConfigureAwait(false);
-
- var user = authorization.User;
- return await _sessionManager.LogSessionActivity(
- authorization.Client,
- authorization.Version,
- authorization.DeviceId,
- authorization.Device,
- requestContext.GetNormalizedRemoteIp().ToString(),
- user).ConfigureAwait(false);
- }
-
- public Task GetSession(object requestContext)
- {
- return GetSession((HttpContext)requestContext);
- }
-
- public async Task GetUser(HttpContext requestContext)
- {
- var session = await GetSession(requestContext).ConfigureAwait(false);
-
- return session.UserId.Equals(default)
- ? null
- : _userManager.GetUserById(session.UserId);
- }
-
- public Task GetUser(object requestContext)
- {
- return GetUser(((HttpRequest)requestContext).HttpContext);
- }
- }
-}
diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
index 35fd5caae..c654828b1 100644
--- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
+++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
@@ -6,6 +6,7 @@ using System.Linq;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Api.Extensions;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Net;
@@ -53,7 +54,6 @@ namespace Emby.Server.Implementations.Session
private readonly ISessionManager _sessionManager;
private readonly ILogger _logger;
private readonly ILoggerFactory _loggerFactory;
- private readonly IAuthorizationContext _authorizationContext;
///
/// The KeepAlive cancellation token.
@@ -66,17 +66,14 @@ namespace Emby.Server.Implementations.Session
/// The logger.
/// The session manager.
/// The logger factory.
- /// The authorization context.
public SessionWebSocketListener(
ILogger logger,
ISessionManager sessionManager,
- ILoggerFactory loggerFactory,
- IAuthorizationContext authorizationContext)
+ ILoggerFactory loggerFactory)
{
_logger = logger;
_sessionManager = sessionManager;
_loggerFactory = loggerFactory;
- _authorizationContext = authorizationContext;
}
///
@@ -110,21 +107,18 @@ namespace Emby.Server.Implementations.Session
private async Task GetSession(HttpContext httpContext, string remoteEndpoint)
{
- var authorizationInfo = await _authorizationContext.GetAuthorizationInfo(httpContext)
- .ConfigureAwait(false);
-
- if (!authorizationInfo.IsAuthenticated)
+ if (!httpContext.User.Identity?.IsAuthenticated ?? false)
{
return null;
}
- var deviceId = authorizationInfo.DeviceId;
+ var deviceId = httpContext.User.GetDeviceId();
if (httpContext.Request.Query.TryGetValue("deviceId", out var queryDeviceId))
{
deviceId = queryDeviceId;
}
- return await _sessionManager.GetSessionByAuthenticationToken(authorizationInfo.Token, deviceId, remoteEndpoint)
+ return await _sessionManager.GetSessionByAuthenticationToken(httpContext.User.GetToken(), deviceId, remoteEndpoint)
.ConfigureAwait(false);
}
diff --git a/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs b/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs
index 13d3257df..92ee1dd59 100644
--- a/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs
+++ b/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs
@@ -1,4 +1,5 @@
using System.Security.Claims;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
@@ -51,21 +52,21 @@ namespace Jellyfin.Api.Auth
bool requiredDownloadPermission = false)
{
// ApiKey is currently global admin, always allow.
- var isApiKey = ClaimHelpers.GetIsApiKey(claimsPrincipal);
+ var isApiKey = claimsPrincipal.GetIsApiKey();
if (isApiKey)
{
return true;
}
// Ensure claim has userId.
- var userId = ClaimHelpers.GetUserId(claimsPrincipal);
- if (!userId.HasValue)
+ var userId = claimsPrincipal.GetUserId();
+ if (userId.Equals(default))
{
return false;
}
// Ensure userId links to a valid user.
- var user = _userManager.GetUserById(userId.Value);
+ var user = _userManager.GetUserById(userId);
if (user == null)
{
return false;
diff --git a/Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs b/Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs
index e6c04eb08..cdd7d8a52 100644
--- a/Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs
+++ b/Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Data.Enums;
using MediaBrowser.Common.Net;
@@ -44,14 +45,14 @@ namespace Jellyfin.Api.Auth.SyncPlayAccessPolicy
return Task.CompletedTask;
}
- var userId = ClaimHelpers.GetUserId(context.User);
- var user = _userManager.GetUserById(userId!.Value);
+ var userId = context.User.GetUserId();
+ var user = _userManager.GetUserById(userId);
if (requirement.RequiredAccess == SyncPlayAccessRequirementType.HasAccess)
{
if (user.SyncPlayAccess == SyncPlayUserAccessType.CreateAndJoinGroups
|| user.SyncPlayAccess == SyncPlayUserAccessType.JoinGroups
- || _syncPlayManager.IsUserActive(userId.Value))
+ || _syncPlayManager.IsUserActive(userId))
{
context.Succeed(requirement);
}
@@ -85,7 +86,7 @@ namespace Jellyfin.Api.Auth.SyncPlayAccessPolicy
}
else if (requirement.RequiredAccess == SyncPlayAccessRequirementType.IsInGroup)
{
- if (_syncPlayManager.IsUserActive(userId.Value))
+ if (_syncPlayManager.IsUserActive(userId))
{
context.Succeed(requirement);
}
diff --git a/Jellyfin.Api/Controllers/ArtistsController.cs b/Jellyfin.Api/Controllers/ArtistsController.cs
index 44796bcc4..c059cb198 100644
--- a/Jellyfin.Api/Controllers/ArtistsController.cs
+++ b/Jellyfin.Api/Controllers/ArtistsController.cs
@@ -120,7 +120,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableTotalRecordCount = true)
{
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = null;
@@ -323,7 +323,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableTotalRecordCount = true)
{
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = null;
@@ -463,7 +463,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult GetArtistByName([FromRoute, Required] string name, [FromQuery] Guid? userId)
{
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
var item = _libraryManager.GetArtist(name, dtoOptions);
diff --git a/Jellyfin.Api/Controllers/ClientLogController.cs b/Jellyfin.Api/Controllers/ClientLogController.cs
index 98fd22430..ed073a687 100644
--- a/Jellyfin.Api/Controllers/ClientLogController.cs
+++ b/Jellyfin.Api/Controllers/ClientLogController.cs
@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.ClientLogDtos;
using MediaBrowser.Controller.ClientEvent;
@@ -69,10 +70,10 @@ namespace Jellyfin.Api.Controllers
private (string ClientName, string ClientVersion) GetRequestInformation()
{
- var clientName = ClaimHelpers.GetClient(HttpContext.User) ?? "unknown-client";
- var clientVersion = ClaimHelpers.GetIsApiKey(HttpContext.User)
+ var clientName = HttpContext.User.GetClient() ?? "unknown-client";
+ var clientVersion = HttpContext.User.GetIsApiKey()
? "apikey"
- : ClaimHelpers.GetVersion(HttpContext.User) ?? "unknown-version";
+ : HttpContext.User.GetVersion() ?? "unknown-version";
return (clientName, clientVersion);
}
diff --git a/Jellyfin.Api/Controllers/CollectionController.cs b/Jellyfin.Api/Controllers/CollectionController.cs
index 8a98d856c..effc9ed7a 100644
--- a/Jellyfin.Api/Controllers/CollectionController.cs
+++ b/Jellyfin.Api/Controllers/CollectionController.cs
@@ -6,7 +6,6 @@ using Jellyfin.Api.Extensions;
using Jellyfin.Api.ModelBinders;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Collections;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
@@ -23,22 +22,18 @@ namespace Jellyfin.Api.Controllers
{
private readonly ICollectionManager _collectionManager;
private readonly IDtoService _dtoService;
- private readonly IAuthorizationContext _authContext;
///
/// Initializes a new instance of the class.
///
/// Instance of interface.
/// Instance of interface.
- /// Instance of interface.
public CollectionController(
ICollectionManager collectionManager,
- IDtoService dtoService,
- IAuthorizationContext authContext)
+ IDtoService dtoService)
{
_collectionManager = collectionManager;
_dtoService = dtoService;
- _authContext = authContext;
}
///
@@ -58,7 +53,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] Guid? parentId,
[FromQuery] bool isLocked = false)
{
- var userId = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).UserId;
+ var userId = User.GetUserId();
var item = await _collectionManager.CreateCollectionAsync(new CollectionCreationOptions
{
@@ -69,7 +64,7 @@ namespace Jellyfin.Api.Controllers
UserIds = new[] { userId }
}).ConfigureAwait(false);
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
var dto = _dtoService.GetBaseItemDto(item, dtoOptions);
diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs
index 3ed80f662..0f4d3c1eb 100644
--- a/Jellyfin.Api/Controllers/DynamicHlsController.cs
+++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs
@@ -20,7 +20,6 @@ using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.IO;
@@ -46,7 +45,6 @@ namespace Jellyfin.Api.Controllers
private readonly ILibraryManager _libraryManager;
private readonly IUserManager _userManager;
private readonly IDlnaManager _dlnaManager;
- private readonly IAuthorizationContext _authContext;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IMediaEncoder _mediaEncoder;
@@ -65,7 +63,6 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
@@ -80,7 +77,6 @@ namespace Jellyfin.Api.Controllers
ILibraryManager libraryManager,
IUserManager userManager,
IDlnaManager dlnaManager,
- IAuthorizationContext authContext,
IMediaSourceManager mediaSourceManager,
IServerConfigurationManager serverConfigurationManager,
IMediaEncoder mediaEncoder,
@@ -95,7 +91,6 @@ namespace Jellyfin.Api.Controllers
_libraryManager = libraryManager;
_userManager = userManager;
_dlnaManager = dlnaManager;
- _authContext = authContext;
_mediaSourceManager = mediaSourceManager;
_serverConfigurationManager = serverConfigurationManager;
_mediaEncoder = mediaEncoder;
@@ -287,8 +282,7 @@ namespace Jellyfin.Api.Controllers
var cancellationToken = cancellationTokenSource.Token;
var state = await StreamingHelpers.GetStreamingState(
streamingRequest,
- Request,
- _authContext,
+ HttpContext,
_mediaSourceManager,
_userManager,
_libraryManager,
@@ -1393,8 +1387,7 @@ namespace Jellyfin.Api.Controllers
{
using var state = await StreamingHelpers.GetStreamingState(
streamingRequest,
- Request,
- _authContext,
+ HttpContext,
_mediaSourceManager,
_userManager,
_libraryManager,
@@ -1434,8 +1427,7 @@ namespace Jellyfin.Api.Controllers
var state = await StreamingHelpers.GetStreamingState(
streamingRequest,
- Request,
- _authContext,
+ HttpContext,
_mediaSourceManager,
_userManager,
_libraryManager,
diff --git a/Jellyfin.Api/Controllers/GenresController.cs b/Jellyfin.Api/Controllers/GenresController.cs
index e28a50750..611643bd8 100644
--- a/Jellyfin.Api/Controllers/GenresController.cs
+++ b/Jellyfin.Api/Controllers/GenresController.cs
@@ -92,7 +92,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableTotalRecordCount = true)
{
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
@@ -157,7 +157,7 @@ namespace Jellyfin.Api.Controllers
public ActionResult GetGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
{
var dtoOptions = new DtoOptions()
- .AddClientFields(Request);
+ .AddClientFields(User);
Genre? item;
if (genreName.Contains(BaseItem.SlugChar, StringComparison.OrdinalIgnoreCase))
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index 6c7842c7b..f092bd882 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -17,7 +17,6 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Branding;
using MediaBrowser.Model.Drawing;
@@ -44,11 +43,9 @@ namespace Jellyfin.Api.Controllers
private readonly IProviderManager _providerManager;
private readonly IImageProcessor _imageProcessor;
private readonly IFileSystem _fileSystem;
- private readonly IAuthorizationContext _authContext;
private readonly ILogger _logger;
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IApplicationPaths _appPaths;
- private readonly IImageEncoder _imageEncoder;
///
/// Initializes a new instance of the class.
@@ -58,33 +55,27 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
public ImageController(
IUserManager userManager,
ILibraryManager libraryManager,
IProviderManager providerManager,
IImageProcessor imageProcessor,
IFileSystem fileSystem,
- IAuthorizationContext authContext,
ILogger logger,
IServerConfigurationManager serverConfigurationManager,
- IApplicationPaths appPaths,
- IImageEncoder imageEncoder)
+ IApplicationPaths appPaths)
{
_userManager = userManager;
_libraryManager = libraryManager;
_providerManager = providerManager;
_imageProcessor = imageProcessor;
_fileSystem = fileSystem;
- _authContext = authContext;
_logger = logger;
_serverConfigurationManager = serverConfigurationManager;
_appPaths = appPaths;
- _imageEncoder = imageEncoder;
}
///
@@ -108,7 +99,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] ImageType imageType,
[FromQuery] int? index = null)
{
- if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, HttpContext.User, userId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the image.");
}
@@ -155,7 +146,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] ImageType imageType,
[FromRoute] int index)
{
- if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, HttpContext.User, userId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the image.");
}
@@ -201,7 +192,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] ImageType imageType,
[FromQuery] int? index = null)
{
- if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, HttpContext.User, userId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to delete the image.");
}
@@ -245,7 +236,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] ImageType imageType,
[FromRoute] int index)
{
- if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, HttpContext.User, userId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to delete the image.");
}
diff --git a/Jellyfin.Api/Controllers/InstantMixController.cs b/Jellyfin.Api/Controllers/InstantMixController.cs
index 9abea5938..2e0d3cb99 100644
--- a/Jellyfin.Api/Controllers/InstantMixController.cs
+++ b/Jellyfin.Api/Controllers/InstantMixController.cs
@@ -79,7 +79,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -115,7 +115,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(album, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -151,7 +151,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(playlist, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -186,7 +186,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromGenres(new[] { name }, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -222,7 +222,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -258,7 +258,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
@@ -331,7 +331,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
return GetResult(items, user, limit, dtoOptions);
diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs
index 4d09070db..3c7c375d4 100644
--- a/Jellyfin.Api/Controllers/ItemsController.cs
+++ b/Jellyfin.Api/Controllers/ItemsController.cs
@@ -10,7 +10,6 @@ using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -34,7 +33,6 @@ namespace Jellyfin.Api.Controllers
private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _localization;
private readonly IDtoService _dtoService;
- private readonly IAuthorizationContext _authContext;
private readonly ILogger _logger;
private readonly ISessionManager _sessionManager;
@@ -45,7 +43,6 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
public ItemsController(
@@ -53,7 +50,6 @@ namespace Jellyfin.Api.Controllers
ILibraryManager libraryManager,
ILocalizationManager localization,
IDtoService dtoService,
- IAuthorizationContext authContext,
ILogger logger,
ISessionManager sessionManager)
{
@@ -61,7 +57,6 @@ namespace Jellyfin.Api.Controllers
_libraryManager = libraryManager;
_localization = localization;
_dtoService = dtoService;
- _authContext = authContext;
_logger = logger;
_sessionManager = sessionManager;
}
@@ -244,21 +239,20 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableTotalRecordCount = true,
[FromQuery] bool? enableImages = true)
{
- var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
-
+ var isApiKey = User.GetIsApiKey();
// if api key is used (auth.IsApiKey == true), then `user` will be null throughout this method
- var user = !auth.IsApiKey && userId.HasValue && !userId.Value.Equals(default)
+ var user = !isApiKey && userId.HasValue && !userId.Value.Equals(default)
? _userManager.GetUserById(userId.Value)
: null;
// beyond this point, we're either using an api key or we have a valid user
- if (!auth.IsApiKey && user is null)
+ if (!isApiKey && user is null)
{
return BadRequest("userId is required");
}
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
if (includeItemTypes.Length == 1
@@ -288,12 +282,12 @@ namespace Jellyfin.Api.Controllers
includeItemTypes = new[] { BaseItemKind.Playlist };
}
- var enabledChannels = auth.IsApiKey
+ var enabledChannels = isApiKey
? Array.Empty()
: user!.GetPreferenceValues(PreferenceKind.EnabledChannels);
// api keys are always enabled for all folders
- bool isInEnabledFolder = auth.IsApiKey
+ bool isInEnabledFolder = isApiKey
|| Array.IndexOf(user!.GetPreferenceValues(PreferenceKind.EnabledFolders), item.Id) != -1
// Assume all folders inside an EnabledChannel are enabled
|| Array.IndexOf(enabledChannels, item.Id) != -1
@@ -850,7 +844,7 @@ namespace Jellyfin.Api.Controllers
var user = _userManager.GetUserById(userId);
var parentIdGuid = parentId ?? Guid.Empty;
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var ancestorIds = Array.Empty();
diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs
index 4cc17dd0f..e9492a6a4 100644
--- a/Jellyfin.Api/Controllers/LibraryController.cs
+++ b/Jellyfin.Api/Controllers/LibraryController.cs
@@ -24,7 +24,6 @@ using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Configuration;
@@ -50,7 +49,6 @@ namespace Jellyfin.Api.Controllers
private readonly ILibraryManager _libraryManager;
private readonly IUserManager _userManager;
private readonly IDtoService _dtoService;
- private readonly IAuthorizationContext _authContext;
private readonly IActivityManager _activityManager;
private readonly ILocalizationManager _localization;
private readonly ILibraryMonitor _libraryMonitor;
@@ -64,7 +62,6 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
@@ -75,7 +72,6 @@ namespace Jellyfin.Api.Controllers
ILibraryManager libraryManager,
IUserManager userManager,
IDtoService dtoService,
- IAuthorizationContext authContext,
IActivityManager activityManager,
ILocalizationManager localization,
ILibraryMonitor libraryMonitor,
@@ -86,7 +82,6 @@ namespace Jellyfin.Api.Controllers
_libraryManager = libraryManager;
_userManager = userManager;
_dtoService = dtoService;
- _authContext = authContext;
_activityManager = activityManager;
_localization = localization;
_libraryMonitor = libraryMonitor;
@@ -184,7 +179,7 @@ namespace Jellyfin.Api.Controllers
item = parent;
}
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
var items = themeItems
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
.ToArray();
@@ -250,7 +245,7 @@ namespace Jellyfin.Api.Controllers
item = parent;
}
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
var items = themeItems
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
.ToArray();
@@ -331,11 +326,10 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
- public async Task DeleteItem(Guid itemId)
+ public ActionResult DeleteItem(Guid itemId)
{
var item = _libraryManager.GetItemById(itemId);
- var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
- var user = auth.User;
+ var user = _userManager.GetUserById(User.GetUserId());
if (!item.CanDelete(user))
{
@@ -361,7 +355,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
- public async Task DeleteItems([FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] ids)
+ public ActionResult DeleteItems([FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] ids)
{
if (ids.Length == 0)
{
@@ -371,8 +365,7 @@ namespace Jellyfin.Api.Controllers
foreach (var i in ids)
{
var item = _libraryManager.GetItemById(i);
- var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
- var user = auth.User;
+ var user = _userManager.GetUserById(User.GetUserId());
if (!item.CanDelete(user))
{
@@ -453,7 +446,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
BaseItem? parent = item.GetParent();
while (parent != null)
@@ -505,7 +498,7 @@ namespace Jellyfin.Api.Controllers
items = items.Where(i => i.IsHidden == val).ToList();
}
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
var resultArray = _dtoService.GetBaseItemDtos(items, dtoOptions);
return new QueryResult(resultArray);
}
@@ -622,9 +615,7 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
-
- var user = auth.User;
+ var user = _userManager.GetUserById(User.GetUserId());
if (user != null)
{
@@ -643,7 +634,7 @@ namespace Jellyfin.Api.Controllers
if (user != null)
{
- await LogDownloadAsync(item, user, auth).ConfigureAwait(false);
+ await LogDownloadAsync(item, user).ConfigureAwait(false);
}
var path = item.Path;
@@ -704,7 +695,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request);
+ .AddClientFields(User);
var program = item as IHasProgramAttributes;
bool? isMovie = item is Movie || (program != null && program.IsMovie) || item is Trailer;
@@ -892,16 +883,16 @@ namespace Jellyfin.Api.Controllers
: item;
}
- private async Task LogDownloadAsync(BaseItem item, User user, AuthorizationInfo auth)
+ private async Task LogDownloadAsync(BaseItem item, User user)
{
try
{
await _activityManager.CreateAsync(new ActivityLog(
string.Format(CultureInfo.InvariantCulture, _localization.GetLocalizedString("UserDownloadingItemWithValues"), user.Username, item.Name),
"UserDownloadingContent",
- auth.UserId)
+ User.GetUserId())
{
- ShortOverview = string.Format(CultureInfo.InvariantCulture, _localization.GetLocalizedString("AppDeviceValues"), auth.Client, auth.Device),
+ ShortOverview = string.Format(CultureInfo.InvariantCulture, _localization.GetLocalizedString("AppDeviceValues"), User.GetClient(), User.GetDevice()),
}).ConfigureAwait(false);
}
catch
diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs
index 05340099b..394df0f58 100644
--- a/Jellyfin.Api/Controllers/LiveTvController.cs
+++ b/Jellyfin.Api/Controllers/LiveTvController.cs
@@ -17,6 +17,7 @@ using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.LiveTvDtos;
using Jellyfin.Data.Enums;
using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@@ -24,6 +25,7 @@ using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.LiveTv;
@@ -45,10 +47,10 @@ namespace Jellyfin.Api.Controllers
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILibraryManager _libraryManager;
private readonly IDtoService _dtoService;
- private readonly ISessionContext _sessionContext;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IConfigurationManager _configurationManager;
private readonly TranscodingJobHelper _transcodingJobHelper;
+ private readonly ISessionManager _sessionManager;
///
/// Initializes a new instance of the class.
@@ -58,30 +60,30 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the class.
+ /// Instance of the interface.
public LiveTvController(
ILiveTvManager liveTvManager,
IUserManager userManager,
IHttpClientFactory httpClientFactory,
ILibraryManager libraryManager,
IDtoService dtoService,
- ISessionContext sessionContext,
IMediaSourceManager mediaSourceManager,
IConfigurationManager configurationManager,
- TranscodingJobHelper transcodingJobHelper)
+ TranscodingJobHelper transcodingJobHelper,
+ ISessionManager sessionManager)
{
_liveTvManager = liveTvManager;
_userManager = userManager;
_httpClientFactory = httpClientFactory;
_libraryManager = libraryManager;
_dtoService = dtoService;
- _sessionContext = sessionContext;
_mediaSourceManager = mediaSourceManager;
_configurationManager = configurationManager;
_transcodingJobHelper = transcodingJobHelper;
+ _sessionManager = sessionManager;
}
///
@@ -154,7 +156,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool addCurrentProgram = true)
{
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var channelResult = _liveTvManager.GetInternalChannels(
@@ -219,7 +221,7 @@ namespace Jellyfin.Api.Controllers
: _libraryManager.GetItemById(channelId);
var dtoOptions = new DtoOptions()
- .AddClientFields(Request);
+ .AddClientFields(User);
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
}
@@ -272,7 +274,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableTotalRecordCount = true)
{
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
return _liveTvManager.GetRecordings(
@@ -410,7 +412,7 @@ namespace Jellyfin.Api.Controllers
var item = recordingId.Equals(default) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(recordingId);
var dtoOptions = new DtoOptions()
- .AddClientFields(Request);
+ .AddClientFields(User);
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
}
@@ -599,7 +601,7 @@ namespace Jellyfin.Api.Controllers
}
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
return await _liveTvManager.GetPrograms(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
}
@@ -653,7 +655,7 @@ namespace Jellyfin.Api.Controllers
}
var dtoOptions = new DtoOptions { Fields = body.Fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(body.EnableImages, body.EnableUserData, body.ImageTypeLimit, body.EnableImageTypes);
return await _liveTvManager.GetPrograms(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
}
@@ -719,7 +721,7 @@ namespace Jellyfin.Api.Controllers
};
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
return await _liveTvManager.GetRecommendedProgramsAsync(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
}
@@ -1210,9 +1212,16 @@ namespace Jellyfin.Api.Controllers
private async Task AssertUserCanManageLiveTv()
{
- var user = await _sessionContext.GetUser(Request).ConfigureAwait(false);
-
- if (user == null)
+ var user = _userManager.GetUserById(User.GetUserId());
+ var session = await _sessionManager.LogSessionActivity(
+ User.GetClient(),
+ User.GetVersion(),
+ User.GetDeviceId(),
+ User.GetDevice(),
+ HttpContext.GetNormalizedRemoteIp().ToString(),
+ user).ConfigureAwait(false);
+
+ if (session.UserId.Equals(default))
{
throw new SecurityException("Anonymous live tv management is not allowed.");
}
diff --git a/Jellyfin.Api/Controllers/MediaInfoController.cs b/Jellyfin.Api/Controllers/MediaInfoController.cs
index d2852ed01..c111e9218 100644
--- a/Jellyfin.Api/Controllers/MediaInfoController.cs
+++ b/Jellyfin.Api/Controllers/MediaInfoController.cs
@@ -6,12 +6,12 @@ using System.Net.Mime;
using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.MediaInfoDtos;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.MediaInfo;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
@@ -31,7 +31,6 @@ namespace Jellyfin.Api.Controllers
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IDeviceManager _deviceManager;
private readonly ILibraryManager _libraryManager;
- private readonly IAuthorizationContext _authContext;
private readonly ILogger _logger;
private readonly MediaInfoHelper _mediaInfoHelper;
@@ -41,21 +40,18 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the .
public MediaInfoController(
IMediaSourceManager mediaSourceManager,
IDeviceManager deviceManager,
ILibraryManager libraryManager,
- IAuthorizationContext authContext,
ILogger logger,
MediaInfoHelper mediaInfoHelper)
{
_mediaSourceManager = mediaSourceManager;
_deviceManager = deviceManager;
_libraryManager = libraryManager;
- _authContext = authContext;
_logger = logger;
_mediaInfoHelper = mediaInfoHelper;
}
@@ -122,14 +118,12 @@ namespace Jellyfin.Api.Controllers
[FromQuery, ParameterObsolete] bool? allowAudioStreamCopy,
[FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] PlaybackInfoDto? playbackInfoDto)
{
- var authInfo = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
-
var profile = playbackInfoDto?.DeviceProfile;
_logger.LogDebug("GetPostedPlaybackInfo profile: {@Profile}", profile);
if (profile == null)
{
- var caps = _deviceManager.GetCapabilities(authInfo.DeviceId);
+ var caps = _deviceManager.GetCapabilities(User.GetDeviceId());
if (caps != null)
{
profile = caps.DeviceProfile;
@@ -176,7 +170,7 @@ namespace Jellyfin.Api.Controllers
item,
mediaSource,
profile,
- authInfo,
+ User,
maxStreamingBitrate ?? profile.MaxStreamingBitrate,
startTimeTicks ?? 0,
mediaSourceId ?? string.Empty,
@@ -203,7 +197,7 @@ namespace Jellyfin.Api.Controllers
if (mediaSource != null && mediaSource.RequiresOpening && string.IsNullOrWhiteSpace(mediaSource.LiveStreamId))
{
var openStreamResult = await _mediaInfoHelper.OpenMediaSource(
- Request,
+ HttpContext,
new LiveStreamRequest
{
AudioStreamIndex = audioStreamIndex,
@@ -276,7 +270,7 @@ namespace Jellyfin.Api.Controllers
EnableDirectStream = enableDirectStream ?? openLiveStreamDto?.EnableDirectStream ?? true,
DirectPlayProtocols = openLiveStreamDto?.DirectPlayProtocols ?? new[] { MediaProtocol.Http }
};
- return await _mediaInfoHelper.OpenMediaSource(Request, request).ConfigureAwait(false);
+ return await _mediaInfoHelper.OpenMediaSource(HttpContext, request).ConfigureAwait(false);
}
///
diff --git a/Jellyfin.Api/Controllers/MoviesController.cs b/Jellyfin.Api/Controllers/MoviesController.cs
index 466944704..8195fc760 100644
--- a/Jellyfin.Api/Controllers/MoviesController.cs
+++ b/Jellyfin.Api/Controllers/MoviesController.cs
@@ -72,7 +72,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId.Value);
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request);
+ .AddClientFields(User);
var categories = new List();
diff --git a/Jellyfin.Api/Controllers/MusicGenresController.cs b/Jellyfin.Api/Controllers/MusicGenresController.cs
index 0499b2985..f4fb5f44a 100644
--- a/Jellyfin.Api/Controllers/MusicGenresController.cs
+++ b/Jellyfin.Api/Controllers/MusicGenresController.cs
@@ -92,7 +92,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableTotalRecordCount = true)
{
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
@@ -145,7 +145,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult GetMusicGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
{
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
MusicGenre? item;
diff --git a/Jellyfin.Api/Controllers/PersonsController.cs b/Jellyfin.Api/Controllers/PersonsController.cs
index 33f1aea39..42be969b2 100644
--- a/Jellyfin.Api/Controllers/PersonsController.cs
+++ b/Jellyfin.Api/Controllers/PersonsController.cs
@@ -79,7 +79,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool? enableImages = true)
{
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
@@ -119,7 +119,7 @@ namespace Jellyfin.Api.Controllers
public ActionResult GetPerson([FromRoute, Required] string name, [FromQuery] Guid? userId)
{
var dtoOptions = new DtoOptions()
- .AddClientFields(Request);
+ .AddClientFields(User);
var item = _libraryManager.GetPerson(name);
if (item == null)
diff --git a/Jellyfin.Api/Controllers/PlaylistsController.cs b/Jellyfin.Api/Controllers/PlaylistsController.cs
index ad85f2fb2..fb045f891 100644
--- a/Jellyfin.Api/Controllers/PlaylistsController.cs
+++ b/Jellyfin.Api/Controllers/PlaylistsController.cs
@@ -200,7 +200,7 @@ namespace Jellyfin.Api.Controllers
}
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var dtos = _dtoService.GetBaseItemDtos(items.Select(i => i.Item2).ToList(), dtoOptions, user);
diff --git a/Jellyfin.Api/Controllers/PlaystateController.cs b/Jellyfin.Api/Controllers/PlaystateController.cs
index 6dee1c219..0dd4bf803 100644
--- a/Jellyfin.Api/Controllers/PlaystateController.cs
+++ b/Jellyfin.Api/Controllers/PlaystateController.cs
@@ -3,11 +3,11 @@ using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Session;
@@ -29,7 +29,6 @@ namespace Jellyfin.Api.Controllers
private readonly IUserDataManager _userDataRepository;
private readonly ILibraryManager _libraryManager;
private readonly ISessionManager _sessionManager;
- private readonly IAuthorizationContext _authContext;
private readonly ILogger _logger;
private readonly TranscodingJobHelper _transcodingJobHelper;
@@ -40,7 +39,6 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Th singleton.
public PlaystateController(
@@ -48,7 +46,6 @@ namespace Jellyfin.Api.Controllers
IUserDataManager userDataRepository,
ILibraryManager libraryManager,
ISessionManager sessionManager,
- IAuthorizationContext authContext,
ILoggerFactory loggerFactory,
TranscodingJobHelper transcodingJobHelper)
{
@@ -56,7 +53,6 @@ namespace Jellyfin.Api.Controllers
_userDataRepository = userDataRepository;
_libraryManager = libraryManager;
_sessionManager = sessionManager;
- _authContext = authContext;
_logger = loggerFactory.CreateLogger();
_transcodingJobHelper = transcodingJobHelper;
@@ -78,7 +74,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery, ModelBinder(typeof(LegacyDateTimeModelBinder))] DateTime? datePlayed)
{
var user = _userManager.GetUserById(userId);
- var session = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ var session = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var dto = UpdatePlayedStatus(user, itemId, true, datePlayed);
foreach (var additionalUserInfo in session.AdditionalUsers)
{
@@ -101,7 +97,7 @@ namespace Jellyfin.Api.Controllers
public async Task> MarkUnplayedItem([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
{
var user = _userManager.GetUserById(userId);
- var session = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ var session = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var dto = UpdatePlayedStatus(user, itemId, false, null);
foreach (var additionalUserInfo in session.AdditionalUsers)
{
@@ -123,7 +119,7 @@ namespace Jellyfin.Api.Controllers
public async Task ReportPlaybackStart([FromBody] PlaybackStartInfo playbackStartInfo)
{
playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
- playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
return NoContent();
}
@@ -139,7 +135,7 @@ namespace Jellyfin.Api.Controllers
public async Task ReportPlaybackProgress([FromBody] PlaybackProgressInfo playbackProgressInfo)
{
playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
- playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
return NoContent();
}
@@ -171,11 +167,10 @@ namespace Jellyfin.Api.Controllers
_logger.LogDebug("ReportPlaybackStopped PlaySessionId: {0}", playbackStopInfo.PlaySessionId ?? string.Empty);
if (!string.IsNullOrWhiteSpace(playbackStopInfo.PlaySessionId))
{
- var authInfo = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
- await _transcodingJobHelper.KillTranscodingJobs(authInfo.DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
+ await _transcodingJobHelper.KillTranscodingJobs(User.GetDeviceId()!, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
}
- playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
return NoContent();
}
@@ -221,7 +216,7 @@ namespace Jellyfin.Api.Controllers
};
playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
- playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
return NoContent();
}
@@ -279,7 +274,7 @@ namespace Jellyfin.Api.Controllers
};
playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
- playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);;
await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
return NoContent();
}
@@ -321,11 +316,10 @@ namespace Jellyfin.Api.Controllers
_logger.LogDebug("ReportPlaybackStopped PlaySessionId: {0}", playbackStopInfo.PlaySessionId ?? string.Empty);
if (!string.IsNullOrWhiteSpace(playbackStopInfo.PlaySessionId))
{
- var authInfo = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
- await _transcodingJobHelper.KillTranscodingJobs(authInfo.DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
+ await _transcodingJobHelper.KillTranscodingJobs(User.GetDeviceId()!, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
}
- playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);;
await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
return NoContent();
}
diff --git a/Jellyfin.Api/Controllers/QuickConnectController.cs b/Jellyfin.Api/Controllers/QuickConnectController.cs
index 1df26355f..77d88475f 100644
--- a/Jellyfin.Api/Controllers/QuickConnectController.cs
+++ b/Jellyfin.Api/Controllers/QuickConnectController.cs
@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Authentication;
@@ -104,15 +105,15 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task> AuthorizeQuickConnect([FromQuery, Required] string code)
{
- var userId = ClaimHelpers.GetUserId(Request.HttpContext.User);
- if (!userId.HasValue)
+ var userId = User.GetUserId();
+ if (userId.Equals(default))
{
return StatusCode(StatusCodes.Status403Forbidden, "Unknown user id");
}
try
{
- return await _quickConnect.AuthorizeRequest(userId.Value, code).ConfigureAwait(false);
+ return await _quickConnect.AuthorizeRequest(userId, code).ConfigureAwait(false);
}
catch (AuthenticationException)
{
diff --git a/Jellyfin.Api/Controllers/SessionController.cs b/Jellyfin.Api/Controllers/SessionController.cs
index 860bccb9b..28415555e 100644
--- a/Jellyfin.Api/Controllers/SessionController.cs
+++ b/Jellyfin.Api/Controllers/SessionController.cs
@@ -5,13 +5,13 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.SessionDtos;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Session;
@@ -29,7 +29,6 @@ namespace Jellyfin.Api.Controllers
{
private readonly ISessionManager _sessionManager;
private readonly IUserManager _userManager;
- private readonly IAuthorizationContext _authContext;
private readonly IDeviceManager _deviceManager;
///
@@ -37,17 +36,14 @@ namespace Jellyfin.Api.Controllers
///
/// Instance of interface.
/// Instance of interface.
- /// Instance of interface.
/// Instance of interface.
public SessionController(
ISessionManager sessionManager,
IUserManager userManager,
- IAuthorizationContext authContext,
IDeviceManager deviceManager)
{
_sessionManager = sessionManager;
_userManager = userManager;
- _authContext = authContext;
_deviceManager = deviceManager;
}
@@ -139,7 +135,7 @@ namespace Jellyfin.Api.Controllers
};
await _sessionManager.SendBrowseCommand(
- await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
+ await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false),
sessionId,
command,
CancellationToken.None)
@@ -186,7 +182,7 @@ namespace Jellyfin.Api.Controllers
};
await _sessionManager.SendPlayCommand(
- await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
+ await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false),
sessionId,
playRequest,
CancellationToken.None)
@@ -214,7 +210,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] string? controllingUserId)
{
await _sessionManager.SendPlaystateCommand(
- await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
+ await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false),
sessionId,
new PlaystateRequest()
{
@@ -242,14 +238,14 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] string sessionId,
[FromRoute, Required] GeneralCommandType command)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var generalCommand = new GeneralCommand
{
Name = command,
ControllingUserId = currentSession.UserId
};
- await _sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None);
+ await _sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None).ConfigureAwait(false);
return NoContent();
}
@@ -268,7 +264,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] string sessionId,
[FromRoute, Required] GeneralCommandType command)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var generalCommand = new GeneralCommand
{
@@ -296,8 +292,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] string sessionId,
[FromBody, Required] GeneralCommand command)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authContext, Request)
- .ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
if (command == null)
{
@@ -336,7 +331,7 @@ namespace Jellyfin.Api.Controllers
}
await _sessionManager.SendMessageCommand(
- await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
+ await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false),
sessionId,
command,
CancellationToken.None)
@@ -405,7 +400,7 @@ namespace Jellyfin.Api.Controllers
{
if (string.IsNullOrWhiteSpace(id))
{
- id = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ id = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
}
_sessionManager.ReportCapabilities(id, new ClientCapabilities
@@ -435,7 +430,7 @@ namespace Jellyfin.Api.Controllers
{
if (string.IsNullOrWhiteSpace(id))
{
- id = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ id = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
}
_sessionManager.ReportCapabilities(id, capabilities.ToClientCapabilities());
@@ -457,7 +452,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] string? sessionId,
[FromQuery, Required] string? itemId)
{
- string session = sessionId ?? await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
+ string session = sessionId ?? await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
_sessionManager.ReportNowViewingItem(session, itemId);
return NoContent();
@@ -473,9 +468,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task ReportSessionEnded()
{
- AuthorizationInfo auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
-
- await _sessionManager.Logout(auth.Token).ConfigureAwait(false);
+ await _sessionManager.Logout(User.GetToken()).ConfigureAwait(false);
return NoContent();
}
diff --git a/Jellyfin.Api/Controllers/StudiosController.cs b/Jellyfin.Api/Controllers/StudiosController.cs
index 053c7baaa..1288fb512 100644
--- a/Jellyfin.Api/Controllers/StudiosController.cs
+++ b/Jellyfin.Api/Controllers/StudiosController.cs
@@ -88,7 +88,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableTotalRecordCount = true)
{
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
@@ -140,7 +140,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult GetStudio([FromRoute, Required] string name, [FromQuery] Guid? userId)
{
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
var item = _libraryManager.GetStudio(name);
if (userId.HasValue && !userId.Equals(default))
diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs
index 16acedcf3..1258a9876 100644
--- a/Jellyfin.Api/Controllers/SubtitleController.cs
+++ b/Jellyfin.Api/Controllers/SubtitleController.cs
@@ -11,13 +11,13 @@ using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Models.SubtitleDtos;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Model.Entities;
@@ -45,7 +45,6 @@ namespace Jellyfin.Api.Controllers
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IProviderManager _providerManager;
private readonly IFileSystem _fileSystem;
- private readonly IAuthorizationContext _authContext;
private readonly ILogger _logger;
///
@@ -58,7 +57,6 @@ namespace Jellyfin.Api.Controllers
/// Instance of interface.
/// Instance of interface.
/// Instance of interface.
- /// Instance of interface.
/// Instance of interface.
public SubtitleController(
IServerConfigurationManager serverConfigurationManager,
@@ -68,7 +66,6 @@ namespace Jellyfin.Api.Controllers
IMediaSourceManager mediaSourceManager,
IProviderManager providerManager,
IFileSystem fileSystem,
- IAuthorizationContext authContext,
ILogger logger)
{
_serverConfigurationManager = serverConfigurationManager;
@@ -78,7 +75,6 @@ namespace Jellyfin.Api.Controllers
_mediaSourceManager = mediaSourceManager;
_providerManager = providerManager;
_fileSystem = fileSystem;
- _authContext = authContext;
_logger = logger;
}
@@ -361,7 +357,7 @@ namespace Jellyfin.Api.Controllers
long positionTicks = 0;
- var accessToken = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).Token;
+ var accessToken = User.GetToken();
while (positionTicks < runtime)
{
diff --git a/Jellyfin.Api/Controllers/SuggestionsController.cs b/Jellyfin.Api/Controllers/SuggestionsController.cs
index e9c46dcf3..1cf528153 100644
--- a/Jellyfin.Api/Controllers/SuggestionsController.cs
+++ b/Jellyfin.Api/Controllers/SuggestionsController.cs
@@ -67,7 +67,7 @@ namespace Jellyfin.Api.Controllers
? null
: _userManager.GetUserById(userId);
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
var result = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
{
OrderBy = new[] { (ItemSortBy.Random, SortOrder.Descending) },
diff --git a/Jellyfin.Api/Controllers/SyncPlayController.cs b/Jellyfin.Api/Controllers/SyncPlayController.cs
index c6b70f3d2..e194fc556 100644
--- a/Jellyfin.Api/Controllers/SyncPlayController.cs
+++ b/Jellyfin.Api/Controllers/SyncPlayController.cs
@@ -5,7 +5,7 @@ using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.SyncPlayDtos;
-using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Session;
using MediaBrowser.Controller.SyncPlay;
using MediaBrowser.Controller.SyncPlay.PlaybackRequests;
@@ -24,23 +24,23 @@ namespace Jellyfin.Api.Controllers
public class SyncPlayController : BaseJellyfinApiController
{
private readonly ISessionManager _sessionManager;
- private readonly IAuthorizationContext _authorizationContext;
private readonly ISyncPlayManager _syncPlayManager;
+ private readonly IUserManager _userManager;
///
/// Initializes a new instance of the class.
///
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
+ /// Instance of the interface.
public SyncPlayController(
ISessionManager sessionManager,
- IAuthorizationContext authorizationContext,
- ISyncPlayManager syncPlayManager)
+ ISyncPlayManager syncPlayManager,
+ IUserManager userManager)
{
_sessionManager = sessionManager;
- _authorizationContext = authorizationContext;
_syncPlayManager = syncPlayManager;
+ _userManager = userManager;
}
///
@@ -55,7 +55,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayCreateGroup(
[FromBody, Required] NewGroupRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new NewGroupRequest(requestData.GroupName);
_syncPlayManager.NewGroup(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -73,7 +73,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayJoinGroup(
[FromBody, Required] JoinGroupRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new JoinGroupRequest(requestData.GroupId);
_syncPlayManager.JoinGroup(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -89,7 +89,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
public async Task SyncPlayLeaveGroup()
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new LeaveGroupRequest();
_syncPlayManager.LeaveGroup(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -105,7 +105,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.SyncPlayJoinGroup)]
public async Task>> SyncPlayGetGroups()
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new ListGroupsRequest();
return Ok(_syncPlayManager.ListGroups(currentSession, syncPlayRequest));
}
@@ -122,7 +122,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlaySetNewQueue(
[FromBody, Required] PlayRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new PlayGroupRequest(
requestData.PlayingQueue,
requestData.PlayingItemPosition,
@@ -143,7 +143,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlaySetPlaylistItem(
[FromBody, Required] SetPlaylistItemRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new SetPlaylistItemGroupRequest(requestData.PlaylistItemId);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayRemoveFromPlaylist(
[FromBody, Required] RemoveFromPlaylistRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new RemoveFromPlaylistGroupRequest(requestData.PlaylistItemIds, requestData.ClearPlaylist, requestData.ClearPlayingItem);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -179,7 +179,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayMovePlaylistItem(
[FromBody, Required] MovePlaylistItemRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new MovePlaylistItemGroupRequest(requestData.PlaylistItemId, requestData.NewIndex);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -197,7 +197,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayQueue(
[FromBody, Required] QueueRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new QueueGroupRequest(requestData.ItemIds, requestData.Mode);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -213,7 +213,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
public async Task SyncPlayUnpause()
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new UnpauseGroupRequest();
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -229,7 +229,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
public async Task SyncPlayPause()
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new PauseGroupRequest();
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -245,7 +245,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
public async Task SyncPlayStop()
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new StopGroupRequest();
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -263,7 +263,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlaySeek(
[FromBody, Required] SeekRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new SeekGroupRequest(requestData.PositionTicks);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -281,7 +281,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayBuffering(
[FromBody, Required] BufferRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new BufferGroupRequest(
requestData.When,
requestData.PositionTicks,
@@ -303,7 +303,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayReady(
[FromBody, Required] ReadyRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new ReadyGroupRequest(
requestData.When,
requestData.PositionTicks,
@@ -325,7 +325,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlaySetIgnoreWait(
[FromBody, Required] IgnoreWaitRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new IgnoreWaitGroupRequest(requestData.IgnoreWait);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -343,7 +343,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayNextItem(
[FromBody, Required] NextItemRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new NextItemGroupRequest(requestData.PlaylistItemId);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -361,7 +361,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayPreviousItem(
[FromBody, Required] PreviousItemRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new PreviousItemGroupRequest(requestData.PlaylistItemId);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -379,7 +379,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlaySetRepeatMode(
[FromBody, Required] SetRepeatModeRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new SetRepeatModeGroupRequest(requestData.Mode);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -397,7 +397,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlaySetShuffleMode(
[FromBody, Required] SetShuffleModeRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new SetShuffleModeGroupRequest(requestData.Mode);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
@@ -414,7 +414,7 @@ namespace Jellyfin.Api.Controllers
public async Task SyncPlayPing(
[FromBody, Required] PingRequestDto requestData)
{
- var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
+ var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new PingGroupRequest(requestData.Ping);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
diff --git a/Jellyfin.Api/Controllers/TvShowsController.cs b/Jellyfin.Api/Controllers/TvShowsController.cs
index e39d05a6f..ea13ceb91 100644
--- a/Jellyfin.Api/Controllers/TvShowsController.cs
+++ b/Jellyfin.Api/Controllers/TvShowsController.cs
@@ -89,7 +89,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableRewatching = false)
{
var options = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var result = _tvSeriesManager.GetNextUp(
@@ -154,7 +154,7 @@ namespace Jellyfin.Api.Controllers
var parentIdGuid = parentId ?? Guid.Empty;
var options = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
@@ -223,7 +223,7 @@ namespace Jellyfin.Api.Controllers
List episodes;
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
if (seasonId.HasValue) // Season id was supplied. Get episodes by season id.
@@ -349,7 +349,7 @@ namespace Jellyfin.Api.Controllers
});
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var returnItems = _dtoService.GetBaseItemDtos(seasons, dtoOptions, user);
diff --git a/Jellyfin.Api/Controllers/UniversalAudioController.cs b/Jellyfin.Api/Controllers/UniversalAudioController.cs
index c463fb08a..01e13b4fe 100644
--- a/Jellyfin.Api/Controllers/UniversalAudioController.cs
+++ b/Jellyfin.Api/Controllers/UniversalAudioController.cs
@@ -6,13 +6,13 @@ using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.StreamingDtos;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.MediaInfo;
using Microsoft.AspNetCore.Authorization;
@@ -28,7 +28,6 @@ namespace Jellyfin.Api.Controllers
[Route("")]
public class UniversalAudioController : BaseJellyfinApiController
{
- private readonly IAuthorizationContext _authorizationContext;
private readonly ILibraryManager _libraryManager;
private readonly ILogger _logger;
private readonly MediaInfoHelper _mediaInfoHelper;
@@ -38,21 +37,18 @@ namespace Jellyfin.Api.Controllers
///
/// Initializes a new instance of the class.
///
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
/// Instance of .
/// Instance of .
/// Instance of .
public UniversalAudioController(
- IAuthorizationContext authorizationContext,
ILibraryManager libraryManager,
ILogger logger,
MediaInfoHelper mediaInfoHelper,
AudioHelper audioHelper,
DynamicHlsHelper dynamicHlsHelper)
{
- _authorizationContext = authorizationContext;
_libraryManager = libraryManager;
_logger = logger;
_mediaInfoHelper = mediaInfoHelper;
@@ -111,16 +107,12 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool enableRedirection = true)
{
var deviceProfile = GetDeviceProfile(container, transcodingContainer, audioCodec, transcodingProtocol, breakOnNonKeyFrames, transcodingAudioChannels, maxAudioSampleRate, maxAudioBitDepth, maxAudioChannels);
- var authorizationInfo = await _authorizationContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
- authorizationInfo.DeviceId = deviceId;
if (!userId.HasValue || userId.Value.Equals(Guid.Empty))
{
- userId = authorizationInfo.UserId;
+ userId = User.GetUserId();
}
- var authInfo = await _authorizationContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
-
_logger.LogInformation("GetPostedPlaybackInfo profile: {@Profile}", deviceProfile);
var info = await _mediaInfoHelper.GetPlaybackInfo(
@@ -138,7 +130,7 @@ namespace Jellyfin.Api.Controllers
item,
sourceInfo,
deviceProfile,
- authInfo,
+ User,
maxStreamingBitrate ?? deviceProfile.MaxStreamingBitrate,
startTimeTicks ?? 0,
mediaSourceId ?? string.Empty,
diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs
index d1109bebc..004690541 100644
--- a/Jellyfin.Api/Controllers/UserController.cs
+++ b/Jellyfin.Api/Controllers/UserController.cs
@@ -4,6 +4,7 @@ using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.UserDtos;
using Jellyfin.Data.Enums;
@@ -264,7 +265,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] Guid userId,
[FromBody, Required] UpdateUserPassword request)
{
- if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the password.");
}
@@ -282,7 +283,7 @@ namespace Jellyfin.Api.Controllers
}
else
{
- if (!HttpContext.User.IsInRole(UserRoles.Administrator))
+ if (!User.IsInRole(UserRoles.Administrator))
{
var success = await _userManager.AuthenticateUser(
user.Username,
@@ -299,7 +300,7 @@ namespace Jellyfin.Api.Controllers
await _userManager.ChangePassword(user, request.NewPw).ConfigureAwait(false);
- var currentToken = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).Token;
+ var currentToken = User.GetToken();
await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false);
}
@@ -325,7 +326,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] Guid userId,
[FromBody, Required] UpdateUserEasyPassword request)
{
- if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the easy password.");
}
@@ -367,7 +368,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] Guid userId,
[FromBody, Required] UserDto updateUser)
{
- if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, false).ConfigureAwait(false))
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User update not allowed.");
}
@@ -427,7 +428,7 @@ namespace Jellyfin.Api.Controllers
return StatusCode(StatusCodes.Status403Forbidden, "There must be at least one enabled user in the system.");
}
- var currentToken = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).Token;
+ var currentToken = User.GetToken();
await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false);
}
@@ -452,7 +453,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] Guid userId,
[FromBody, Required] UserConfiguration userConfig)
{
- if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, false).ConfigureAwait(false))
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
{
return StatusCode(StatusCodes.Status403Forbidden, "User configuration update not allowed");
}
@@ -536,13 +537,13 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult GetCurrentUser()
{
- var userId = ClaimHelpers.GetUserId(Request.HttpContext.User);
- if (userId is null)
+ var userId = User.GetUserId();
+ if (userId.Equals(default))
{
return BadRequest();
}
- var user = _userManager.GetUserById(userId.Value);
+ var user = _userManager.GetUserById(userId);
if (user == null)
{
return BadRequest();
@@ -567,7 +568,7 @@ namespace Jellyfin.Api.Controllers
if (filterByDevice)
{
- var deviceId = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).DeviceId;
+ var deviceId = User.GetDeviceId();
if (!string.IsNullOrWhiteSpace(deviceId))
{
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index 940fa27a7..ee8a17b62 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -81,7 +81,7 @@ namespace Jellyfin.Api.Controllers
await RefreshItemOnDemandIfNeeded(item).ConfigureAwait(false);
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
}
@@ -98,7 +98,7 @@ namespace Jellyfin.Api.Controllers
{
var user = _userManager.GetUserById(userId);
var item = _libraryManager.GetUserRootFolder();
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
}
@@ -120,7 +120,7 @@ namespace Jellyfin.Api.Controllers
: _libraryManager.GetItemById(itemId);
var items = await _libraryManager.GetIntros(item, user).ConfigureAwait(false);
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
var dtos = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray();
return new QueryResult(dtos);
@@ -200,7 +200,7 @@ namespace Jellyfin.Api.Controllers
? _libraryManager.GetUserRootFolder()
: _libraryManager.GetItemById(itemId);
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
if (item is IHasTrailers hasTrailers)
{
@@ -230,7 +230,7 @@ namespace Jellyfin.Api.Controllers
? _libraryManager.GetUserRootFolder()
: _libraryManager.GetItemById(itemId);
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
return Ok(item
.GetExtras()
@@ -280,7 +280,7 @@ namespace Jellyfin.Api.Controllers
}
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
var list = _userViewManager.GetLatestItems(
diff --git a/Jellyfin.Api/Controllers/UserViewsController.cs b/Jellyfin.Api/Controllers/UserViewsController.cs
index 04732ccf2..85d154cac 100644
--- a/Jellyfin.Api/Controllers/UserViewsController.cs
+++ b/Jellyfin.Api/Controllers/UserViewsController.cs
@@ -85,7 +85,7 @@ namespace Jellyfin.Api.Controllers
var folders = _userViewManager.GetUserViews(query);
- var dtoOptions = new DtoOptions().AddClientFields(Request);
+ var dtoOptions = new DtoOptions().AddClientFields(User);
var fields = dtoOptions.Fields.ToList();
fields.Add(ItemFields.PrimaryImageAspectRatio);
diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs
index 4e2895934..bf08ad376 100644
--- a/Jellyfin.Api/Controllers/VideosController.cs
+++ b/Jellyfin.Api/Controllers/VideosController.cs
@@ -43,7 +43,6 @@ namespace Jellyfin.Api.Controllers
private readonly IUserManager _userManager;
private readonly IDtoService _dtoService;
private readonly IDlnaManager _dlnaManager;
- private readonly IAuthorizationContext _authContext;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IMediaEncoder _mediaEncoder;
@@ -61,7 +60,6 @@ namespace Jellyfin.Api.Controllers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
@@ -74,7 +72,6 @@ namespace Jellyfin.Api.Controllers
IUserManager userManager,
IDtoService dtoService,
IDlnaManager dlnaManager,
- IAuthorizationContext authContext,
IMediaSourceManager mediaSourceManager,
IServerConfigurationManager serverConfigurationManager,
IMediaEncoder mediaEncoder,
@@ -87,7 +84,6 @@ namespace Jellyfin.Api.Controllers
_userManager = userManager;
_dtoService = dtoService;
_dlnaManager = dlnaManager;
- _authContext = authContext;
_mediaSourceManager = mediaSourceManager;
_serverConfigurationManager = serverConfigurationManager;
_mediaEncoder = mediaEncoder;
@@ -120,7 +116,7 @@ namespace Jellyfin.Api.Controllers
: _libraryManager.GetItemById(itemId);
var dtoOptions = new DtoOptions();
- dtoOptions = dtoOptions.AddClientFields(Request);
+ dtoOptions = dtoOptions.AddClientFields(User);
BaseItemDto[] items;
if (item is Video video)
@@ -429,8 +425,7 @@ namespace Jellyfin.Api.Controllers
var state = await StreamingHelpers.GetStreamingState(
streamingRequest,
- Request,
- _authContext,
+ HttpContext,
_mediaSourceManager,
_userManager,
_libraryManager,
diff --git a/Jellyfin.Api/Controllers/YearsController.cs b/Jellyfin.Api/Controllers/YearsController.cs
index 7c02e2550..b732bdff3 100644
--- a/Jellyfin.Api/Controllers/YearsController.cs
+++ b/Jellyfin.Api/Controllers/YearsController.cs
@@ -87,7 +87,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool? enableImages = true)
{
var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request)
+ .AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
User? user = userId is null || userId.Value.Equals(default)
@@ -179,7 +179,7 @@ namespace Jellyfin.Api.Controllers
}
var dtoOptions = new DtoOptions()
- .AddClientFields(Request);
+ .AddClientFields(User);
if (userId.HasValue && !userId.Value.Equals(default))
{
diff --git a/Jellyfin.Api/Extensions/ClaimsPrincipalExtensions.cs b/Jellyfin.Api/Extensions/ClaimsPrincipalExtensions.cs
new file mode 100644
index 000000000..6b3e78d4d
--- /dev/null
+++ b/Jellyfin.Api/Extensions/ClaimsPrincipalExtensions.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Linq;
+using System.Security.Claims;
+using Jellyfin.Api.Constants;
+
+namespace Jellyfin.Api.Extensions;
+
+///
+/// Extensions for .
+///
+public static class ClaimsPrincipalExtensions
+{
+ ///
+ /// Get user id from claims.
+ ///
+ /// Current claims principal.
+ /// User id.
+ public static Guid GetUserId(this ClaimsPrincipal user)
+ {
+ var value = GetClaimValue(user, InternalClaimTypes.UserId);
+ return string.IsNullOrEmpty(value)
+ ? default
+ : Guid.Parse(value);
+ }
+
+ ///
+ /// Get device id from claims.
+ ///
+ /// Current claims principal.
+ /// Device id.
+ public static string? GetDeviceId(this ClaimsPrincipal user)
+ => GetClaimValue(user, InternalClaimTypes.DeviceId);
+
+ ///
+ /// Get device from claims.
+ ///
+ /// Current claims principal.
+ /// Device.
+ public static string? GetDevice(this ClaimsPrincipal user)
+ => GetClaimValue(user, InternalClaimTypes.Device);
+
+ ///
+ /// Get client from claims.
+ ///
+ /// Current claims principal.
+ /// Client.
+ public static string? GetClient(this ClaimsPrincipal user)
+ => GetClaimValue(user, InternalClaimTypes.Client);
+
+ ///
+ /// Get version from claims.
+ ///
+ /// Current claims principal.
+ /// Version.
+ public static string? GetVersion(this ClaimsPrincipal user)
+ => GetClaimValue(user, InternalClaimTypes.Version);
+
+ ///
+ /// Get token from claims.
+ ///
+ /// Current claims principal.
+ /// Token.
+ public static string? GetToken(this ClaimsPrincipal user)
+ => GetClaimValue(user, InternalClaimTypes.Token);
+
+ ///
+ /// Gets a flag specifying whether the request is using an api key.
+ ///
+ /// Current claims principal.
+ /// The flag specifying whether the request is using an api key.
+ public static bool GetIsApiKey(this ClaimsPrincipal user)
+ {
+ var claimValue = GetClaimValue(user, InternalClaimTypes.IsApiKey);
+ return !string.IsNullOrEmpty(claimValue)
+ && bool.TryParse(claimValue, out var parsedClaimValue)
+ && parsedClaimValue;
+ }
+
+ private static string? GetClaimValue(in ClaimsPrincipal user, string name)
+ => user.Claims.FirstOrDefault(claim => claim.Type.Equals(name, StringComparison.OrdinalIgnoreCase))?.Value;
+}
diff --git a/Jellyfin.Api/Extensions/DtoExtensions.cs b/Jellyfin.Api/Extensions/DtoExtensions.cs
index 5e338b67d..9e784f7c4 100644
--- a/Jellyfin.Api/Extensions/DtoExtensions.cs
+++ b/Jellyfin.Api/Extensions/DtoExtensions.cs
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
-using Jellyfin.Api.Helpers;
+using System.Security.Claims;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Model.Entities;
@@ -22,14 +22,14 @@ namespace Jellyfin.Api.Extensions
/// Legacy order: 2.
///
/// DtoOptions object.
- /// Current request.
+ /// Current claims principal.
/// Modified DtoOptions object.
internal static DtoOptions AddClientFields(
- this DtoOptions dtoOptions, HttpRequest request)
+ this DtoOptions dtoOptions, ClaimsPrincipal user)
{
dtoOptions.Fields ??= Array.Empty();
- string? client = ClaimHelpers.GetClient(request.HttpContext.User);
+ string? client = user.GetClient();
// No client in claim
if (string.IsNullOrEmpty(client))
diff --git a/Jellyfin.Api/Helpers/AudioHelper.cs b/Jellyfin.Api/Helpers/AudioHelper.cs
index 27497cd59..bc83ff48a 100644
--- a/Jellyfin.Api/Helpers/AudioHelper.cs
+++ b/Jellyfin.Api/Helpers/AudioHelper.cs
@@ -11,7 +11,6 @@ using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net;
using Microsoft.AspNetCore.Http;
@@ -25,7 +24,6 @@ namespace Jellyfin.Api.Helpers
public class AudioHelper
{
private readonly IDlnaManager _dlnaManager;
- private readonly IAuthorizationContext _authContext;
private readonly IUserManager _userManager;
private readonly ILibraryManager _libraryManager;
private readonly IMediaSourceManager _mediaSourceManager;
@@ -41,7 +39,6 @@ namespace Jellyfin.Api.Helpers
/// Initializes a new instance of the class.
///
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
@@ -54,7 +51,6 @@ namespace Jellyfin.Api.Helpers
/// Instance of .
public AudioHelper(
IDlnaManager dlnaManager,
- IAuthorizationContext authContext,
IUserManager userManager,
ILibraryManager libraryManager,
IMediaSourceManager mediaSourceManager,
@@ -67,7 +63,6 @@ namespace Jellyfin.Api.Helpers
EncodingHelper encodingHelper)
{
_dlnaManager = dlnaManager;
- _authContext = authContext;
_userManager = userManager;
_libraryManager = libraryManager;
_mediaSourceManager = mediaSourceManager;
@@ -102,8 +97,7 @@ namespace Jellyfin.Api.Helpers
using var state = await StreamingHelpers.GetStreamingState(
streamingRequest,
- _httpContextAccessor.HttpContext.Request,
- _authContext,
+ _httpContextAccessor.HttpContext,
_mediaSourceManager,
_userManager,
_libraryManager,
diff --git a/Jellyfin.Api/Helpers/ClaimHelpers.cs b/Jellyfin.Api/Helpers/ClaimHelpers.cs
deleted file mode 100644
index c1c2f93b4..000000000
--- a/Jellyfin.Api/Helpers/ClaimHelpers.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System;
-using System.Linq;
-using System.Security.Claims;
-using Jellyfin.Api.Constants;
-
-namespace Jellyfin.Api.Helpers
-{
- ///
- /// Claim Helpers.
- ///
- public static class ClaimHelpers
- {
- ///
- /// Get user id from claims.
- ///
- /// Current claims principal.
- /// User id.
- public static Guid? GetUserId(in ClaimsPrincipal user)
- {
- var value = GetClaimValue(user, InternalClaimTypes.UserId);
- return string.IsNullOrEmpty(value)
- ? null
- : Guid.Parse(value);
- }
-
- ///
- /// Get device id from claims.
- ///
- /// Current claims principal.
- /// Device id.
- public static string? GetDeviceId(in ClaimsPrincipal user)
- => GetClaimValue(user, InternalClaimTypes.DeviceId);
-
- ///
- /// Get device from claims.
- ///
- /// Current claims principal.
- /// Device.
- public static string? GetDevice(in ClaimsPrincipal user)
- => GetClaimValue(user, InternalClaimTypes.Device);
-
- ///
- /// Get client from claims.
- ///
- /// Current claims principal.
- /// Client.
- public static string? GetClient(in ClaimsPrincipal user)
- => GetClaimValue(user, InternalClaimTypes.Client);
-
- ///
- /// Get version from claims.
- ///
- /// Current claims principal.
- /// Version.
- public static string? GetVersion(in ClaimsPrincipal user)
- => GetClaimValue(user, InternalClaimTypes.Version);
-
- ///
- /// Get token from claims.
- ///
- /// Current claims principal.
- /// Token.
- public static string? GetToken(in ClaimsPrincipal user)
- => GetClaimValue(user, InternalClaimTypes.Token);
-
- ///
- /// Gets a flag specifying whether the request is using an api key.
- ///
- /// Current claims principal.
- /// The flag specifying whether the request is using an api key.
- public static bool GetIsApiKey(in ClaimsPrincipal user)
- {
- var claimValue = GetClaimValue(user, InternalClaimTypes.IsApiKey);
- return !string.IsNullOrEmpty(claimValue)
- && bool.TryParse(claimValue, out var parsedClaimValue)
- && parsedClaimValue;
- }
-
- private static string? GetClaimValue(in ClaimsPrincipal user, string name)
- {
- return user?.Identities
- .SelectMany(c => c.Claims)
- .Where(claim => claim.Type.Equals(name, StringComparison.OrdinalIgnoreCase))
- .Select(claim => claim.Value)
- .FirstOrDefault();
- }
- }
-}
diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
index 83c9141a9..fa392e567 100644
--- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
+++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
@@ -7,6 +7,7 @@ using System.Security.Claims;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Models.StreamingDtos;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
@@ -15,7 +16,6 @@ using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Net;
@@ -34,7 +34,6 @@ namespace Jellyfin.Api.Helpers
private readonly ILibraryManager _libraryManager;
private readonly IUserManager _userManager;
private readonly IDlnaManager _dlnaManager;
- private readonly IAuthorizationContext _authContext;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IMediaEncoder _mediaEncoder;
@@ -51,7 +50,6 @@ namespace Jellyfin.Api.Helpers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
@@ -65,7 +63,6 @@ namespace Jellyfin.Api.Helpers
ILibraryManager libraryManager,
IUserManager userManager,
IDlnaManager dlnaManager,
- IAuthorizationContext authContext,
IMediaSourceManager mediaSourceManager,
IServerConfigurationManager serverConfigurationManager,
IMediaEncoder mediaEncoder,
@@ -79,7 +76,6 @@ namespace Jellyfin.Api.Helpers
_libraryManager = libraryManager;
_userManager = userManager;
_dlnaManager = dlnaManager;
- _authContext = authContext;
_mediaSourceManager = mediaSourceManager;
_serverConfigurationManager = serverConfigurationManager;
_mediaEncoder = mediaEncoder;
@@ -128,8 +124,7 @@ namespace Jellyfin.Api.Helpers
using var state = await StreamingHelpers.GetStreamingState(
streamingRequest,
- _httpContextAccessor.HttpContext.Request,
- _authContext,
+ _httpContextAccessor.HttpContext,
_mediaSourceManager,
_userManager,
_libraryManager,
@@ -483,7 +478,7 @@ namespace Jellyfin.Api.Helpers
state.Request.MediaSourceId,
stream.Index.ToString(CultureInfo.InvariantCulture),
30.ToString(CultureInfo.InvariantCulture),
- ClaimHelpers.GetToken(user));
+ user.GetToken());
var line = string.Format(
CultureInfo.InvariantCulture,
diff --git a/Jellyfin.Api/Helpers/MediaInfoHelper.cs b/Jellyfin.Api/Helpers/MediaInfoHelper.cs
index 5c05c57a6..11f490bb4 100644
--- a/Jellyfin.Api/Helpers/MediaInfoHelper.cs
+++ b/Jellyfin.Api/Helpers/MediaInfoHelper.cs
@@ -2,9 +2,11 @@
using System.Globalization;
using System.Linq;
using System.Net;
+using System.Security.Claims;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Api.Extensions;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
@@ -15,7 +17,6 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -39,7 +40,6 @@ namespace Jellyfin.Api.Helpers
private readonly ILogger _logger;
private readonly INetworkManager _networkManager;
private readonly IDeviceManager _deviceManager;
- private readonly IAuthorizationContext _authContext;
///
/// Initializes a new instance of the class.
@@ -52,7 +52,6 @@ namespace Jellyfin.Api.Helpers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
public MediaInfoHelper(
IUserManager userManager,
ILibraryManager libraryManager,
@@ -61,8 +60,7 @@ namespace Jellyfin.Api.Helpers
IServerConfigurationManager serverConfigurationManager,
ILogger logger,
INetworkManager networkManager,
- IDeviceManager deviceManager,
- IAuthorizationContext authContext)
+ IDeviceManager deviceManager)
{
_userManager = userManager;
_libraryManager = libraryManager;
@@ -72,7 +70,6 @@ namespace Jellyfin.Api.Helpers
_logger = logger;
_networkManager = networkManager;
_deviceManager = deviceManager;
- _authContext = authContext;
}
///
@@ -147,7 +144,7 @@ namespace Jellyfin.Api.Helpers
/// Item to set data for.
/// Media source info.
/// Device profile.
- /// Authorization info.
+ /// Current claims principal.
/// Max bitrate.
/// Start time ticks.
/// Media source id.
@@ -166,7 +163,7 @@ namespace Jellyfin.Api.Helpers
BaseItem item,
MediaSourceInfo mediaSource,
DeviceProfile profile,
- AuthorizationInfo auth,
+ ClaimsPrincipal claimsPrincipal,
int? maxBitrate,
long startTimeTicks,
string mediaSourceId,
@@ -188,7 +185,7 @@ namespace Jellyfin.Api.Helpers
{
MediaSources = new[] { mediaSource },
Context = EncodingContext.Streaming,
- DeviceId = auth.DeviceId,
+ DeviceId = claimsPrincipal.GetDeviceId(),
ItemId = item.Id,
Profile = profile,
MaxAudioChannels = maxAudioChannels,
@@ -290,7 +287,7 @@ namespace Jellyfin.Api.Helpers
mediaSource.SupportsDirectPlay = false;
mediaSource.SupportsDirectStream = false;
- mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-');
+ mediaSource.TranscodingUrl = streamInfo.ToUrl("-", claimsPrincipal.GetToken()).TrimStart('-');
mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false";
mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false";
mediaSource.TranscodingContainer = streamInfo.Container;
@@ -301,7 +298,7 @@ namespace Jellyfin.Api.Helpers
if (!mediaSource.SupportsDirectPlay && (mediaSource.SupportsTranscoding || mediaSource.SupportsDirectStream))
{
streamInfo.PlayMethod = PlayMethod.Transcode;
- mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-');
+ mediaSource.TranscodingUrl = streamInfo.ToUrl("-", claimsPrincipal.GetToken()).TrimStart('-');
if (!allowVideoStreamCopy)
{
@@ -316,7 +313,7 @@ namespace Jellyfin.Api.Helpers
}
// Do this after the above so that StartPositionTicks is set
- SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token);
+ SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, claimsPrincipal.GetToken());
mediaSource.DefaultAudioStreamIndex = streamInfo.AudioStreamIndex;
}
@@ -384,19 +381,17 @@ namespace Jellyfin.Api.Helpers
///
/// Open media source.
///
- /// Http Request.
+ /// Http Context.
/// Live stream request.
/// A containing the .
- public async Task OpenMediaSource(HttpRequest httpRequest, LiveStreamRequest request)
+ public async Task OpenMediaSource(HttpContext httpContext, LiveStreamRequest request)
{
- var authInfo = await _authContext.GetAuthorizationInfo(httpRequest).ConfigureAwait(false);
-
var result = await _mediaSourceManager.OpenLiveStream(request, CancellationToken.None).ConfigureAwait(false);
var profile = request.DeviceProfile;
if (profile == null)
{
- var clientCapabilities = _deviceManager.GetCapabilities(authInfo.DeviceId);
+ var clientCapabilities = _deviceManager.GetCapabilities(httpContext.User.GetDeviceId());
if (clientCapabilities != null)
{
profile = clientCapabilities.DeviceProfile;
@@ -411,7 +406,7 @@ namespace Jellyfin.Api.Helpers
item,
result.MediaSource,
profile,
- authInfo,
+ httpContext.User,
request.MaxStreamingBitrate,
request.StartTimeTicks ?? 0,
result.MediaSource.Id,
@@ -425,7 +420,7 @@ namespace Jellyfin.Api.Helpers
true,
true,
true,
- httpRequest.HttpContext.GetNormalizedRemoteIp());
+ httpContext.GetNormalizedRemoteIp());
}
else
{
diff --git a/Jellyfin.Api/Helpers/RequestHelpers.cs b/Jellyfin.Api/Helpers/RequestHelpers.cs
index 20427d7fa..8c5af013a 100644
--- a/Jellyfin.Api/Helpers/RequestHelpers.cs
+++ b/Jellyfin.Api/Helpers/RequestHelpers.cs
@@ -1,13 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Security.Claims;
using System.Threading.Tasks;
+using Jellyfin.Api.Constants;
+using Jellyfin.Api.Extensions;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
@@ -55,37 +58,42 @@ namespace Jellyfin.Api.Helpers
///
/// Checks if the user can update an entry.
///
- /// Instance of the interface.
- /// The .
+ /// An instance of the interface.
+ /// The for the current request.
/// The user id.
/// Whether to restrict the user preferences.
/// A whether the user can update the entry.
- internal static async Task AssertCanUpdateUser(IAuthorizationContext authContext, HttpRequest requestContext, Guid userId, bool restrictUserPreferences)
+ internal static bool AssertCanUpdateUser(IUserManager userManager, ClaimsPrincipal claimsPrincipal, Guid userId, bool restrictUserPreferences)
{
- var auth = await authContext.GetAuthorizationInfo(requestContext).ConfigureAwait(false);
-
- var authenticatedUser = auth.User;
+ var authenticatedUserId = claimsPrincipal.GetUserId();
+ var isAdministrator = claimsPrincipal.IsInRole(UserRoles.Administrator);
// If they're going to update the record of another user, they must be an administrator
- if ((!userId.Equals(auth.UserId) && !authenticatedUser.HasPermission(PermissionKind.IsAdministrator))
- || (restrictUserPreferences && !authenticatedUser.EnableUserPreferenceAccess))
+ if (!userId.Equals(authenticatedUserId) && !isAdministrator)
{
return false;
}
- return true;
+ // TODO the EnableUserPreferenceAccess policy does not seem to be used elsewhere
+ if (!restrictUserPreferences || isAdministrator)
+ {
+ return true;
+ }
+
+ var user = userManager.GetUserById(userId);
+ return user.EnableUserPreferenceAccess;
}
- internal static async Task GetSession(ISessionManager sessionManager, IAuthorizationContext authContext, HttpRequest request)
+ internal static async Task GetSession(ISessionManager sessionManager, IUserManager userManager, HttpContext httpContext)
{
- var authorization = await authContext.GetAuthorizationInfo(request).ConfigureAwait(false);
- var user = authorization.User;
+ var userId = httpContext.User.GetUserId();
+ var user = userManager.GetUserById(userId);
var session = await sessionManager.LogSessionActivity(
- authorization.Client,
- authorization.Version,
- authorization.DeviceId,
- authorization.Device,
- request.HttpContext.GetNormalizedRemoteIp().ToString(),
+ httpContext.User.GetClient(),
+ httpContext.User.GetVersion(),
+ httpContext.User.GetDeviceId(),
+ httpContext.User.GetDevice(),
+ httpContext.GetNormalizedRemoteIp().ToString(),
user).ConfigureAwait(false);
if (session == null)
@@ -96,9 +104,9 @@ namespace Jellyfin.Api.Helpers
return session;
}
- internal static async Task GetSessionId(ISessionManager sessionManager, IAuthorizationContext authContext, HttpRequest request)
+ internal static async Task GetSessionId(ISessionManager sessionManager, IUserManager userManager, HttpContext httpContext)
{
- var session = await GetSession(sessionManager, authContext, request).ConfigureAwait(false);
+ var session = await GetSession(sessionManager, userManager, httpContext).ConfigureAwait(false);
return session.Id;
}
diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs
index b552df0a4..370573773 100644
--- a/Jellyfin.Api/Helpers/StreamingHelpers.cs
+++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Models.StreamingDtos;
using Jellyfin.Extensions;
using MediaBrowser.Common.Configuration;
@@ -14,7 +15,6 @@ using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -33,8 +33,7 @@ namespace Jellyfin.Api.Helpers
/// Gets the current streaming state.
///
/// The .
- /// The .
- /// Instance of the interface.
+ /// The .
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
@@ -49,8 +48,7 @@ namespace Jellyfin.Api.Helpers
/// A containing the current .
public static async Task GetStreamingState(
StreamingRequestDto streamingRequest,
- HttpRequest httpRequest,
- IAuthorizationContext authorizationContext,
+ HttpContext httpContext,
IMediaSourceManager mediaSourceManager,
IUserManager userManager,
ILibraryManager libraryManager,
@@ -63,6 +61,7 @@ namespace Jellyfin.Api.Helpers
TranscodingJobType transcodingJobType,
CancellationToken cancellationToken)
{
+ var httpRequest = httpContext.Request;
// Parse the DLNA time seek header
if (!streamingRequest.StartTimeTicks.HasValue)
{
@@ -101,10 +100,10 @@ namespace Jellyfin.Api.Helpers
EnableDlnaHeaders = enableDlnaHeaders
};
- var auth = await authorizationContext.GetAuthorizationInfo(httpRequest).ConfigureAwait(false);
- if (!auth.UserId.Equals(default))
+ var userId = httpContext.User.GetUserId();
+ if (!userId.Equals(default))
{
- state.User = userManager.GetUserById(auth.UserId);
+ state.User = userManager.GetUserById(userId);
}
if (state.IsVideoRequest && !string.IsNullOrWhiteSpace(state.Request.VideoCodec))
diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
index 2adb006e4..c663c6e31 100644
--- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
+++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
@@ -8,6 +8,7 @@ using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Api.Extensions;
using Jellyfin.Api.Models.PlaybackDtos;
using Jellyfin.Api.Models.StreamingDtos;
using Jellyfin.Data.Enums;
@@ -17,7 +18,6 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
@@ -46,7 +46,6 @@ namespace Jellyfin.Api.Helpers
private readonly IAttachmentExtractor _attachmentExtractor;
private readonly IApplicationPaths _appPaths;
- private readonly IAuthorizationContext _authorizationContext;
private readonly EncodingHelper _encodingHelper;
private readonly IFileSystem _fileSystem;
private readonly ILogger _logger;
@@ -55,6 +54,7 @@ namespace Jellyfin.Api.Helpers
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly ISessionManager _sessionManager;
private readonly ILoggerFactory _loggerFactory;
+ private readonly IUserManager _userManager;
///
/// Initializes a new instance of the class.
@@ -67,9 +67,9 @@ namespace Jellyfin.Api.Helpers
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of .
/// Instance of the interface.
+ /// Instance of the interface.
public TranscodingJobHelper(
IAttachmentExtractor attachmentExtractor,
IApplicationPaths appPaths,
@@ -79,9 +79,9 @@ namespace Jellyfin.Api.Helpers
IMediaEncoder mediaEncoder,
IServerConfigurationManager serverConfigurationManager,
ISessionManager sessionManager,
- IAuthorizationContext authorizationContext,
EncodingHelper encodingHelper,
- ILoggerFactory loggerFactory)
+ ILoggerFactory loggerFactory,
+ IUserManager userManager)
{
_attachmentExtractor = attachmentExtractor;
_appPaths = appPaths;
@@ -91,9 +91,9 @@ namespace Jellyfin.Api.Helpers
_mediaEncoder = mediaEncoder;
_serverConfigurationManager = serverConfigurationManager;
_sessionManager = sessionManager;
- _authorizationContext = authorizationContext;
_encodingHelper = encodingHelper;
_loggerFactory = loggerFactory;
+ _userManager = userManager;
DeleteEncodedMediaCache();
@@ -512,8 +512,9 @@ namespace Jellyfin.Api.Helpers
if (state.VideoRequest != null && !EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
{
- var auth = await _authorizationContext.GetAuthorizationInfo(request).ConfigureAwait(false);
- if (auth.User != null && !auth.User.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding))
+ var userId = request.HttpContext.User.GetUserId();
+ var user = userId.Equals(default) ? null : _userManager.GetUserById(userId);
+ if (user != null && !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding))
{
this.OnTranscodeFailedToStart(outputPath, transcodingJobType, state);
diff --git a/MediaBrowser.Controller/Net/ISessionContext.cs b/MediaBrowser.Controller/Net/ISessionContext.cs
deleted file mode 100644
index b48181b3f..000000000
--- a/MediaBrowser.Controller/Net/ISessionContext.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma warning disable CS1591
-
-using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
-using MediaBrowser.Controller.Session;
-using Microsoft.AspNetCore.Http;
-
-namespace MediaBrowser.Controller.Net
-{
- public interface ISessionContext
- {
- Task GetSession(object requestContext);
-
- Task GetUser(object requestContext);
-
- Task GetSession(HttpContext requestContext);
-
- Task GetUser(HttpContext requestContext);
- }
-}
--
cgit v1.2.3