Edit SanitizeUrl to handle also query parameters
modified: Jellyfin.Plugin.TubeArchivistMetadata/Tasks/TAToJellyfinPlaylistsSyncTask.cs modified: Jellyfin.Plugin.TubeArchivistMetadata/TubeArchivist/TubeArchivistApi.cs modified: Jellyfin.Plugin.TubeArchivistMetadata/Utils/Utils.cs
This commit is contained in:
@@ -170,10 +170,18 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.Tasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
processedVideosCount += currentPlaylistVideos;
|
processedVideosCount += currentPlaylistVideos;
|
||||||
|
|
||||||
|
if (totalVideosCount == 0)
|
||||||
|
{
|
||||||
|
progress.Report(100);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
progress.Report(processedVideosCount * 100 / totalVideosCount);
|
progress.Report(processedVideosCount * 100 / totalVideosCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_logger.LogInformation("Time elapsed: {Time}", DateTime.Now - start);
|
_logger.LogInformation("Time elapsed: {Time}", DateTime.Now - start);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist
|
|||||||
{
|
{
|
||||||
url = response.Headers.Location;
|
url = response.Headers.Location;
|
||||||
_logger.LogInformation("{Message}", "Received redirect to: " + url);
|
_logger.LogInformation("{Message}", "Received redirect to: " + url);
|
||||||
response = await client.GetAsync(url).ConfigureAwait(true);
|
response = await client.GetAsync(Utils.SanitizeUrl(Plugin.Instance?.Configuration.TubeArchivistUrl + url)).ConfigureAwait(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("{Message}", url + ": " + response.StatusCode);
|
_logger.LogInformation("{Message}", url + ": " + response.StatusCode);
|
||||||
@@ -238,6 +238,13 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist
|
|||||||
var nextPage = playlists.Paginate.CurrentPage + 1;
|
var nextPage = playlists.Paginate.CurrentPage + 1;
|
||||||
var pagedUrl = new Uri(Utils.SanitizeUrl(Plugin.Instance?.Configuration.TubeArchivistUrl + playlistsEndpoint + "?page=" + nextPage));
|
var pagedUrl = new Uri(Utils.SanitizeUrl(Plugin.Instance?.Configuration.TubeArchivistUrl + playlistsEndpoint + "?page=" + nextPage));
|
||||||
response = await client.GetAsync(pagedUrl).ConfigureAwait(true);
|
response = await client.GetAsync(pagedUrl).ConfigureAwait(true);
|
||||||
|
while (response.StatusCode == HttpStatusCode.Moved)
|
||||||
|
{
|
||||||
|
url = response.Headers.Location;
|
||||||
|
_logger.LogInformation("{Message}", "Received redirect to: " + url);
|
||||||
|
response = await client.GetAsync(Utils.SanitizeUrl(Plugin.Instance?.Configuration.TubeArchivistUrl + url)).ConfigureAwait(true);
|
||||||
|
}
|
||||||
|
|
||||||
_logger.LogInformation("{Message}", pagedUrl + ": " + response.StatusCode);
|
_logger.LogInformation("{Message}", pagedUrl + ": " + response.StatusCode);
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
@@ -258,6 +265,11 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist
|
|||||||
_logger.LogInformation("Pagination info: Current page {CurrentPage} / Last page {LastPage}, Total hits: {TotalHits}", playlists.Paginate.CurrentPage, playlists.Paginate.LastPage, playlists.Paginate.TotalHits);
|
_logger.LogInformation("Pagination info: Current page {CurrentPage} / Last page {LastPage}, Total hits: {TotalHits}", playlists.Paginate.CurrentPage, playlists.Paginate.LastPage, playlists.Paginate.TotalHits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogCritical("Failed to retrieve page {PageNumber} of playlists during pagination.", nextPage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Jellyfin.Plugin.TubeArchivistMetadata.Utilities
|
namespace Jellyfin.Plugin.TubeArchivistMetadata.Utilities
|
||||||
{
|
{
|
||||||
@@ -22,20 +20,59 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata.Utilities
|
|||||||
/// <returns>The URL string without spaces, doubled slashes and with a trailing slash.</returns>
|
/// <returns>The URL string without spaces, doubled slashes and with a trailing slash.</returns>
|
||||||
public static string SanitizeUrl(string inputUrl)
|
public static string SanitizeUrl(string inputUrl)
|
||||||
{
|
{
|
||||||
// Extract the schema part
|
if (string.IsNullOrWhiteSpace(inputUrl))
|
||||||
Match schemaMatch = Regex.Match(inputUrl, @"^(?<schema>https?://)");
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove double slashes and spaces from the remaining part of the URL
|
// Extract the schema part (http:// or https://)
|
||||||
string cleanedPath = Regex.Replace(inputUrl.Substring(schemaMatch.Length), @"[/\s]+", "/");
|
Match schemaMatch = Regex.Match(inputUrl, @"^(?<schema>https?://)", RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
// If no schema found, treat whole string as the rest
|
||||||
|
int schemaLength = schemaMatch.Success ? schemaMatch.Length : 0;
|
||||||
|
|
||||||
|
// Separate the main part from query (?) and fragment (#)
|
||||||
|
string rest = inputUrl.Substring(schemaLength);
|
||||||
|
string pathPart = rest;
|
||||||
|
string queryAndFragment = string.Empty;
|
||||||
|
|
||||||
|
int qIndex = rest.IndexOf('?', StringComparison.Ordinal);
|
||||||
|
int fIndex = rest.IndexOf('#', StringComparison.Ordinal);
|
||||||
|
|
||||||
|
int splitIndex = -1;
|
||||||
|
if (qIndex >= 0 && fIndex >= 0)
|
||||||
|
{
|
||||||
|
splitIndex = Math.Min(qIndex, fIndex);
|
||||||
|
}
|
||||||
|
else if (qIndex >= 0)
|
||||||
|
{
|
||||||
|
splitIndex = qIndex;
|
||||||
|
}
|
||||||
|
else if (fIndex >= 0)
|
||||||
|
{
|
||||||
|
splitIndex = fIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (splitIndex >= 0)
|
||||||
|
{
|
||||||
|
pathPart = rest.Substring(0, splitIndex);
|
||||||
|
queryAndFragment = rest.Substring(splitIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove double slashes and spaces from the path part
|
||||||
|
string cleanedPath = Regex.Replace(pathPart, @"[/\s]+", "/");
|
||||||
|
|
||||||
// Remove slashes at the start
|
// Remove slashes at the start
|
||||||
cleanedPath = cleanedPath.TrimStart('/');
|
cleanedPath = cleanedPath.TrimStart('/');
|
||||||
|
|
||||||
// Add a trailing slash if not already present
|
// Add a trailing slash only when there are no query or fragment parts
|
||||||
|
if (string.IsNullOrEmpty(queryAndFragment))
|
||||||
|
{
|
||||||
cleanedPath = cleanedPath.TrimEnd('/') + "/";
|
cleanedPath = cleanedPath.TrimEnd('/') + "/";
|
||||||
|
}
|
||||||
|
|
||||||
// Combine the schema and cleaned path
|
// Combine the schema and cleaned path and re-append query/fragment
|
||||||
string cleanedUrl = schemaMatch.Groups["schema"].Value + cleanedPath;
|
string cleanedUrl = (schemaMatch.Success ? schemaMatch.Groups["schema"].Value : string.Empty) + cleanedPath + queryAndFragment;
|
||||||
|
|
||||||
return cleanedUrl;
|
return cleanedUrl;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user