Browse Source

proxy server improvements (#996)

pull/997/head
Jason Dove 3 years ago committed by GitHub
parent
commit
2ce0fcb264
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      CHANGELOG.md
  2. 2
      ErsatzTV.Infrastructure/Health/Checks/FileNotFoundHealthCheck.cs
  3. 2
      ErsatzTV.Infrastructure/Health/Checks/UnavailableHealthCheck.cs
  4. 8
      ErsatzTV/Controllers/IptvController.cs
  5. 2
      ErsatzTV/Extensions/StringExtensions.cs
  6. 10
      ErsatzTV/Pages/Artist.razor
  7. 8
      ErsatzTV/Pages/ArtistList.razor
  8. 4
      ErsatzTV/Pages/Channels.razor
  9. 2
      ErsatzTV/Pages/CollectionEditor.razor
  10. 12
      ErsatzTV/Pages/CollectionItems.razor
  11. 8
      ErsatzTV/Pages/Collections.razor
  12. 8
      ErsatzTV/Pages/EpisodeList.razor
  13. 8
      ErsatzTV/Pages/FFmpeg.razor
  14. 2
      ErsatzTV/Pages/FillerPresetEditor.razor
  15. 4
      ErsatzTV/Pages/FillerPresets.razor
  16. 2
      ErsatzTV/Pages/Libraries.razor
  17. 4
      ErsatzTV/Pages/LocalLibraries.razor
  18. 4
      ErsatzTV/Pages/LocalLibraryEditor.razor
  19. 2
      ErsatzTV/Pages/LocalLibraryPathEditor.razor
  20. 6
      ErsatzTV/Pages/Movie.razor
  21. 8
      ErsatzTV/Pages/MovieList.razor
  22. 2
      ErsatzTV/Pages/MultiCollectionEditor.razor
  23. 6
      ErsatzTV/Pages/MusicVideoList.razor
  24. 6
      ErsatzTV/Pages/OtherVideoList.razor
  25. 2
      ErsatzTV/Pages/Playouts.razor
  26. 4
      ErsatzTV/Pages/PlexMediaSources.razor
  27. 6
      ErsatzTV/Pages/Schedules.razor
  28. 26
      ErsatzTV/Pages/Search.razor
  29. 6
      ErsatzTV/Pages/SongList.razor
  30. 12
      ErsatzTV/Pages/TelevisionEpisodeList.razor
  31. 10
      ErsatzTV/Pages/TelevisionSeasonList.razor
  32. 8
      ErsatzTV/Pages/TelevisionSeasonSearchResults.razor
  33. 8
      ErsatzTV/Pages/TelevisionShowList.razor
  34. 2
      ErsatzTV/Pages/TraktLists.razor
  35. 26
      ErsatzTV/Pages/Trash.razor
  36. 4
      ErsatzTV/Pages/Watermarks.razor
  37. 2
      ErsatzTV/Pages/_Host.cshtml
  38. 50
      ErsatzTV/Shared/MainLayout.razor
  39. 2
      ErsatzTV/Shared/MediaCard.razor
  40. 2
      ErsatzTV/Shared/RemoteMediaSourceEditor.razor
  41. 2
      ErsatzTV/Shared/RemoteMediaSourceLibrariesEditor.razor
  42. 2
      ErsatzTV/Shared/RemoteMediaSourcePathReplacementsEditor.razor
  43. 8
      ErsatzTV/Shared/RemoteMediaSources.razor
  44. 10
      ErsatzTV/Startup.cs

2
CHANGELOG.md

@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix bug where tail or fallback filler would sometimes schedule much longer than expected
- This only happened with fixed start schedule items following a schedule item with tail or fallback filler
- Fix NFO reader bug that caused inaccurate warning messages about invalid XML and incomplete metadata
- Fix reverse proxy SSL termination support by supporting `X-Forwarded-Proto` header
### Added
- Add music video credits template system
@ -37,6 +38,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -37,6 +38,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- All groups of part numbers (i.e. all part 1s, all part 2s) will be shuffled
- The playout order will then schedule a random part 1 followed by a random part 2, etc
- Un-split (`nil`) episodes will be randomly placed between re-combined parts (e.g. part1, part2, part3, un-split, part1, part2, part3)
- Add `ETV_BASE_URL` environment variable to support reverse proxies that use paths (e.g. `/ersatztv`)
### Changed
- No longer place watermarks within content by default (e.g. within 4:3 content padded to a 16:9 resolution)

2
ErsatzTV.Infrastructure/Health/Checks/FileNotFoundHealthCheck.cs

@ -58,7 +58,7 @@ public class FileNotFoundHealthCheck : BaseHealthCheck, IFileNotFoundHealthCheck @@ -58,7 +58,7 @@ public class FileNotFoundHealthCheck : BaseHealthCheck, IFileNotFoundHealthCheck
return WarningResult(
$"There are {count} items that do not exist on disk, including the following: {files}",
"/media/trash");
"media/trash");
}
return OkResult();

2
ErsatzTV.Infrastructure/Health/Checks/UnavailableHealthCheck.cs

@ -83,7 +83,7 @@ public class UnavailableHealthCheck : BaseHealthCheck, IUnavailableHealthCheck @@ -83,7 +83,7 @@ public class UnavailableHealthCheck : BaseHealthCheck, IUnavailableHealthCheck
return WarningResult(
$"There are {count} items that are unavailable because ErsatzTV cannot find them on disk, including the following: {files}",
"/search?query=state%3aUnavailable");
"search?query=state%3aUnavailable");
}
return OkResult();

8
ErsatzTV/Controllers/IptvController.cs

@ -77,7 +77,7 @@ public class IptvController : ControllerBase @@ -77,7 +77,7 @@ public class IptvController : ControllerBase
mode = "ts";
break;
default:
return Redirect($"/iptv/channel/{channelNumber}.m3u8");
return Redirect($"~/iptv/channel/{channelNumber}.m3u8");
}
}
}
@ -167,7 +167,7 @@ public class IptvController : ControllerBase @@ -167,7 +167,7 @@ public class IptvController : ControllerBase
mode = "segmenter";
break;
default:
return Redirect($"/iptv/channel/{channelNumber}.ts");
return Redirect($"~/iptv/channel/{channelNumber}.ts");
}
}
}
@ -184,7 +184,7 @@ public class IptvController : ControllerBase @@ -184,7 +184,7 @@ public class IptvController : ControllerBase
"Session started; returning multi-variant playlist for channel {Channel}",
channelNumber);
return Content(GetMultiVariantPlaylist(channelNumber), "application/x-mpegurl");
// return Redirect($"/iptv/session/{channelNumber}/hls.m3u8");
// return Redirect($"~/iptv/session/{channelNumber}/hls.m3u8");
},
error =>
{
@ -195,7 +195,7 @@ public class IptvController : ControllerBase @@ -195,7 +195,7 @@ public class IptvController : ControllerBase
"Session is already active; returning multi-variant playlist for channel {Channel}",
channelNumber);
return Content(GetMultiVariantPlaylist(channelNumber), "application/x-mpegurl");
// return RedirectPreserveMethod($"/iptv/session/{channelNumber}/hls.m3u8");
// return RedirectPreserveMethod($"iptv/session/{channelNumber}/hls.m3u8");
default:
_logger.LogWarning(
"Failed to start segmenter for channel {ChannelNumber}: {Error}",

2
ErsatzTV/Extensions/StringExtensions.cs

@ -33,7 +33,7 @@ public static class StringExtensions @@ -33,7 +33,7 @@ public static class StringExtensions
public static string GetRelativeSearchQuery(this string query)
{
(string key, string value) = EncodeQuery(query);
return $"/search?{key}={value}";
return $"search?{key}={value}";
}
private static string DecodeBase64(this StringValues input) =>

10
ErsatzTV/Pages/Artist.razor

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
<div class="fanart-tint"></div>
@if (!string.IsNullOrWhiteSpace(_artist.FanArt))
{
<img src="@($"/artwork/fanart/{_artist.FanArt}")" alt="fan art"/>
<img src="@($"artwork/fanart/{_artist.FanArt}")" alt="fan art"/>
}
</MudContainer>
<MudContainer MaxWidth="MaxWidth.Large" Style="margin-top: 200px">
@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
{
<img class="mud-elevation-2 mr-6"
style="border-radius: 4px; flex-shrink: 0; height: 220px; width: 220px"
src="@($"/artwork/thumbnails/{_artist.Thumbnail}")" alt="artist thumbnail"/>
src="@($"artwork/thumbnails/{_artist.Thumbnail}")" alt="artist thumbnail"/>
}
<div style="display: flex; flex-direction: column; height: 100%">
<MudText Typo="Typo.h2" Class="media-item-title">@_artist.Name</MudText>
@ -125,7 +125,7 @@ @@ -125,7 +125,7 @@
@if (!string.IsNullOrWhiteSpace(musicVideo.Poster))
{
<MudPaper style="display: flex; flex-direction: column; position: relative">
<MudCardMedia Image="@($"/artwork/thumbnails/{musicVideo.Poster}")" Style="flex-grow: 1; height: 220px; width: 293px;"/>
<MudCardMedia Image="@($"artwork/thumbnails/{musicVideo.Poster}")" Style="flex-grow: 1; height: 220px; width: 293px;"/>
@if (musicVideo.State == MediaItemState.FileNotFound)
{
<div style="position: absolute; right: 10px; top: 8px;">
@ -245,7 +245,7 @@ @@ -245,7 +245,7 @@
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{
await _mediator.Send(new AddArtistToCollection(collection.Id, ArtistId), _cts.Token);
_navigationManager.NavigateTo($"/media/collections/{collection.Id}");
_navigationManager.NavigateTo($"media/collections/{collection.Id}");
}
}
@ -259,7 +259,7 @@ @@ -259,7 +259,7 @@
if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule)
{
await _mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.Artist, null, null, null, ArtistId, PlaybackOrder.Shuffle, null, null, TailMode.None, null, GuideMode.Normal, null, null, null, null, null, null, null, null, null, null), _cts.Token);
_navigationManager.NavigateTo($"/schedules/{schedule.Id}/items");
_navigationManager.NavigateTo($"schedules/{schedule.Id}/items");
}
}

8
ErsatzTV/Pages/ArtistList.razor

@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid">
<FragmentLetterAnchor TCard="ArtistCardViewModel" Cards="@_data.Cards">
<MediaCard Data="@context"
Link="@($"/media/music/artists/{context.ArtistId}")"
Link="@($"media/music/artists/{context.ArtistId}")"
ArtworkKind="ArtworkKind.Thumbnail"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(context, e))"
@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
@if (_data.PageMap.IsSome)
{
<LetterBar PageMap="@_data.PageMap.ValueUnsafe()"
BaseUri="/media/music/artists"
BaseUri="media/music/artists"
Query="@_query"/>
}
@ -99,7 +99,7 @@ @@ -99,7 +99,7 @@
private void PrevPage()
{
string uri = $"/media/music/artists/page/{PageNumber - 1}";
string uri = $"media/music/artists/page/{PageNumber - 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -110,7 +110,7 @@ @@ -110,7 +110,7 @@
private void NextPage()
{
string uri = $"/media/music/artists/page/{PageNumber + 1}";
string uri = $"media/music/artists/page/{PageNumber + 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

4
ErsatzTV/Pages/Channels.razor

@ -58,7 +58,7 @@ @@ -58,7 +58,7 @@
<div style="align-items: center; display: flex;">
<MudTooltip Text="Edit Channel">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Link="@($"/channels/{context.Id}")">
Link="@($"channels/{context.Id}")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Delete Channel">
@ -73,7 +73,7 @@ @@ -73,7 +73,7 @@
<MudTablePager/>
</PagerContent>
</MudTable>
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="/channels/add" Class="mt-4">
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="channels/add" Class="mt-4">
Add Channel
</MudButton>
</MudContainer>

2
ErsatzTV/Pages/CollectionEditor.razor

@ -83,7 +83,7 @@ @@ -83,7 +83,7 @@
_snackbar.Add(error.Value, Severity.Error);
_logger.LogError("Error saving collection: {Error}", error.Value);
},
() => _navigationManager.NavigateTo(_model.Id > 0 ? $"/media/collections/{_model.Id}" : "/media/collections"));
() => _navigationManager.NavigateTo(_model.Id > 0 ? $"media/collections/{_model.Id}" : "media/collections"));
}
}

12
ErsatzTV/Pages/CollectionItems.razor

@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
<div style="align-items: center; display: flex; flex-direction: row;">
<MudText Typo="Typo.h4">@_data.Name</MudText>
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Link="@($"/media/collections/{Id}/edit")"/>
Link="@($"media/collections/{Id}/edit")"/>
</div>
@if (_data.MovieCards.Any())
{
@ -95,7 +95,7 @@ @@ -95,7 +95,7 @@
@foreach (MovieCardViewModel card in OrderMovies(_data.MovieCards))
{
<MediaCard Data="@card"
Link="@($"/media/movies/{card.MovieId}")"
Link="@($"media/movies/{card.MovieId}")"
DeleteClicked="@RemoveMovieFromCollection"
SelectColor="@Color.Error"
SelectClicked="@(e => SelectClicked(card, e))"
@ -118,7 +118,7 @@ @@ -118,7 +118,7 @@
@foreach (TelevisionShowCardViewModel card in _data.ShowCards.OrderBy(m => m.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/tv/shows/{card.TelevisionShowId}")"
Link="@($"media/tv/shows/{card.TelevisionShowId}")"
DeleteClicked="@RemoveShowFromCollection"
SelectColor="@Color.Error"
SelectClicked="@(e => SelectClicked(card, e))"
@ -141,7 +141,7 @@ @@ -141,7 +141,7 @@
@foreach (TelevisionSeasonCardViewModel card in _data.SeasonCards.OrderBy(m => m.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/tv/seasons/{card.TelevisionSeasonId}")"
Link="@($"media/tv/seasons/{card.TelevisionSeasonId}")"
Title="@card.ShowTitle"
Subtitle="@card.Title"
DeleteClicked="@RemoveSeasonFromCollection"
@ -166,7 +166,7 @@ @@ -166,7 +166,7 @@
@foreach (TelevisionEpisodeCardViewModel card in _data.EpisodeCards.OrderBy(e => e.Aired))
{
<MediaCard Data="@card"
Link="@($"/media/tv/seasons/{card.SeasonId}#episode-{card.EpisodeId}")"
Link="@($"media/tv/seasons/{card.SeasonId}#episode-{card.EpisodeId}")"
Title="@card.ShowTitle"
Subtitle="@card.Title"
ContainerClass="media-card-episode-container mx-2"
@ -194,7 +194,7 @@ @@ -194,7 +194,7 @@
@foreach (ArtistCardViewModel card in _data.ArtistCards.OrderBy(e => e.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/music/artists/{card.ArtistId}")"
Link="@($"media/music/artists/{card.ArtistId}")"
ArtworkKind="ArtworkKind.Thumbnail"
DeleteClicked="@RemoveArtistFromCollection"
SelectColor="@Color.Error"

8
ErsatzTV/Pages/Collections.razor

@ -8,10 +8,10 @@ @@ -8,10 +8,10 @@
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<div>
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="/media/collections/add">
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="media/collections/add">
Add Collection
</MudButton>
<MudButton Class="ml-3" Variant="Variant.Filled" Color="Color.Primary" Link="/media/multi-collections/add">
<MudButton Class="ml-3" Variant="Variant.Filled" Color="Color.Primary" Link="media/multi-collections/add">
Add Multi Collection
</MudButton>
</div>
@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
<div style="align-items: center; display: flex;">
<MudTooltip Text="Edit Collection">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Link="@($"/media/collections/{context.Id}")">
Link="@($"media/collections/{context.Id}")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Delete Collection">
@ -76,7 +76,7 @@ @@ -76,7 +76,7 @@
<div style="align-items: center; display: flex;">
<MudTooltip Text="Edit Collection">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Link="@($"/media/multi-collections/{context.Id}/edit")">
Link="@($"media/multi-collections/{context.Id}/edit")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Delete Collection">

8
ErsatzTV/Pages/EpisodeList.razor

@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid">
<FragmentLetterAnchor TCard="TelevisionEpisodeCardViewModel" Cards="@_data.Cards">
<MediaCard Data="@context"
Link="@($"/media/tv/seasons/{context.SeasonId}#episode-{context.EpisodeId}")"
Link="@($"media/tv/seasons/{context.SeasonId}#episode-{context.EpisodeId}")"
Subtitle="@($"{context.ShowTitle} - S{context.Season} E{context.Episode}")"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(context, e))"
@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
@if (_data.PageMap.IsSome)
{
<LetterBar PageMap="@_data.PageMap.ValueUnsafe()"
BaseUri="/media/tv/episodes"
BaseUri="media/tv/episodes"
Query="@_query"/>
}
@ -99,7 +99,7 @@ @@ -99,7 +99,7 @@
private void PrevPage()
{
string uri = $"/media/tv/episodes/page/{PageNumber - 1}";
string uri = $"media/tv/episodes/page/{PageNumber - 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -110,7 +110,7 @@ @@ -110,7 +110,7 @@
private void NextPage()
{
string uri = $"/media/tv/episodes/page/{PageNumber + 1}";
string uri = $"media/tv/episodes/page/{PageNumber + 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

8
ErsatzTV/Pages/FFmpeg.razor

@ -3,8 +3,6 @@ @@ -3,8 +3,6 @@
@implements IDisposable
@inject IDialogService _dialog
@inject IMediator _mediator
@inject ILogger<FFmpeg> _logger
@inject ISnackbar _snackbar
@inject NavigationManager _navigationManager
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
@ -44,7 +42,7 @@ @@ -44,7 +42,7 @@
<div style="align-items: center; display: flex;">
<MudTooltip Text="Edit Profile">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Link="@($"/ffmpeg/{context.Id}")">
Link="@($"ffmpeg/{context.Id}")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Copy Profile">
@ -61,7 +59,7 @@ @@ -61,7 +59,7 @@
</MudTd>
</RowTemplate>
</MudTable>
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="/ffmpeg/add" Class="mt-4">
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="ffmpeg/add" Class="mt-4">
Add Profile
</MudButton>
</MudContainer>
@ -105,7 +103,7 @@ @@ -105,7 +103,7 @@
DialogResult dialogResult = await dialog.Result;
if (!dialogResult.Cancelled && dialogResult.Data is FFmpegProfileViewModel data)
{
_navigationManager.NavigateTo($"/ffmpeg/{data.Id}");
_navigationManager.NavigateTo($"ffmpeg/{data.Id}");
}
}

2
ErsatzTV/Pages/FillerPresetEditor.razor

@ -230,7 +230,7 @@ @@ -230,7 +230,7 @@
_snackbar.Add(error.Value, Severity.Error);
_logger.LogError("Error saving filler preset: {Error}", error.Value);
},
() => _navigationManager.NavigateTo("/media/filler/presets"));
() => _navigationManager.NavigateTo("media/filler/presets"));
}
}

4
ErsatzTV/Pages/FillerPresets.razor

@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<div>
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="/media/filler/presets/add">
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="media/filler/presets/add">
Add Filler Preset
</MudButton>
</div>
@ -49,7 +49,7 @@ @@ -49,7 +49,7 @@
<div style="align-items: center; display: flex;">
<MudTooltip Text="Edit Filler Preset">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Link="@($"/media/filler/presets/{context.Id}/edit")">
Link="@($"media/filler/presets/{context.Id}/edit")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Delete Filler Preset">

2
ErsatzTV/Pages/Libraries.razor

@ -77,7 +77,7 @@ @@ -77,7 +77,7 @@
}
<MudTooltip Text="Search Library">
<MudIconButton Icon="@Icons.Material.Filled.Search"
Link="@($"/search?query=library_id%3a{context.Id}")">
Link="@($"search?query=library_id%3a{context.Id}")">
</MudIconButton>
</MudTooltip>
</div>

4
ErsatzTV/Pages/LocalLibraries.razor

@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
<MudTooltip Text="Edit Library">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Disabled="@_locker.IsLibraryLocked(context.Id)"
Link="@($"/media/sources/local/{context.Id}/edit")">
Link="@($"media/sources/local/{context.Id}/edit")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Delete Library">
@ -45,7 +45,7 @@ @@ -45,7 +45,7 @@
</MudTd>
</RowTemplate>
</MudTable>
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="/media/sources/local/add" Class="mt-4">
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="media/sources/local/add" Class="mt-4">
Add Local Library
</MudButton>
</MudContainer>

4
ErsatzTV/Pages/LocalLibraryEditor.razor

@ -148,7 +148,7 @@ @@ -148,7 +148,7 @@
var request = new MoveLocalLibraryPath(libraryPath.Id, library.Id);
Either<BaseError, Unit> moveResult = await _mediator.Send(request, _cts.Token);
moveResult.Match(
_ => _navigationManager.NavigateTo($"/media/sources/local/{library.Id}/edit"),
_ => _navigationManager.NavigateTo($"media/sources/local/{library.Id}/edit"),
error =>
{
_snackbar.Add(error.Value, Severity.Error);
@ -214,7 +214,7 @@ @@ -214,7 +214,7 @@
_model.Paths.Map(p => p.Path).ToList()), _cts.Token);
result.Match(
_ => _navigationManager.NavigateTo("/media/sources/local"),
_ => _navigationManager.NavigateTo("media/sources/local"),
error =>
{
_snackbar.Add(error.Value, Severity.Error);

2
ErsatzTV/Pages/LocalLibraryPathEditor.razor

@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
if (_locker.LockLibrary(_library.Id))
{
await _channel.WriteAsync(new ScanLocalLibraryIfNeeded(_library.Id), _cts.Token);
_navigationManager.NavigateTo("/media/libraries");
_navigationManager.NavigateTo("media/libraries");
}
});
}

6
ErsatzTV/Pages/Movie.razor

@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
}
else
{
<img src="@($"/artwork/fanart/{_movie.FanArt}")" alt="fan art"/>
<img src="@($"artwork/fanart/{_movie.FanArt}")" alt="fan art"/>
}
}
</MudContainer>
@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
{
<img class="mud-elevation-2"
style="border-radius: 4px; flex-shrink: 0; max-height: 440px;"
src="@($"/artwork/posters/{_movie.Poster}")" alt="movie poster"/>
src="@($"artwork/posters/{_movie.Poster}")" alt="movie poster"/>
}
@if (_movie.MediaItemState == MediaItemState.FileNotFound)
{
@ -249,7 +249,7 @@ @@ -249,7 +249,7 @@
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{
await _mediator.Send(new AddMovieToCollection(collection.Id, MovieId), _cts.Token);
_navigationManager.NavigateTo($"/media/collections/{collection.Id}");
_navigationManager.NavigateTo($"media/collections/{collection.Id}");
}
}

8
ErsatzTV/Pages/MovieList.razor

@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid">
<FragmentLetterAnchor TCard="MovieCardViewModel" Cards="@_data.Cards">
<MediaCard Data="@context"
Link="@($"/media/movies/{context.MovieId}")"
Link="@($"media/movies/{context.MovieId}")"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(context, e))"
IsSelected="@IsSelected(context)"
@ -66,7 +66,7 @@ @@ -66,7 +66,7 @@
@if (_data.PageMap.IsSome)
{
<LetterBar PageMap="@_data.PageMap.ValueUnsafe()"
BaseUri="/media/movies"
BaseUri="media/movies"
Query="@_query"/>
}
@ -98,7 +98,7 @@ @@ -98,7 +98,7 @@
private void PrevPage()
{
string uri = $"/media/movies/page/{PageNumber - 1}";
string uri = $"media/movies/page/{PageNumber - 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -109,7 +109,7 @@ @@ -109,7 +109,7 @@
private void NextPage()
{
string uri = $"/media/movies/page/{PageNumber + 1}";
string uri = $"media/movies/page/{PageNumber + 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

2
ErsatzTV/Pages/MultiCollectionEditor.razor

@ -186,7 +186,7 @@ @@ -186,7 +186,7 @@
_snackbar.Add(error.Value, Severity.Error);
_logger.LogError("Error saving collection: {Error}", error.Value);
},
() => _navigationManager.NavigateTo("/media/collections"));
() => _navigationManager.NavigateTo("media/collections"));
}
}

6
ErsatzTV/Pages/MusicVideoList.razor

@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
@if (_data.PageMap.IsSome)
{
<LetterBar PageMap="@_data.PageMap.ValueUnsafe()"
BaseUri="/media/music/videos"
BaseUri="media/music/videos"
Query="@_query"/>
}
@ -99,7 +99,7 @@ @@ -99,7 +99,7 @@
private void PrevPage()
{
string uri = $"/media/music/videos/page/{PageNumber - 1}";
string uri = $"media/music/videos/page/{PageNumber - 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -110,7 +110,7 @@ @@ -110,7 +110,7 @@
private void NextPage()
{
string uri = $"/media/music/videos/page/{PageNumber + 1}";
string uri = $"media/music/videos/page/{PageNumber + 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

6
ErsatzTV/Pages/OtherVideoList.razor

@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
@if (_data.PageMap.IsSome)
{
<LetterBar PageMap="@_data.PageMap.ValueUnsafe()"
BaseUri="/media/other/videos"
BaseUri="media/other/videos"
Query="@_query"/>
}
@ -99,7 +99,7 @@ @@ -99,7 +99,7 @@
private void PrevPage()
{
string uri = $"/media/other/videos/page/{PageNumber - 1}";
string uri = $"media/other/videos/page/{PageNumber - 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -110,7 +110,7 @@ @@ -110,7 +110,7 @@
private void NextPage()
{
string uri = $"/media/other/videos/page/{PageNumber + 1}";
string uri = $"media/other/videos/page/{PageNumber + 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

2
ErsatzTV/Pages/Playouts.razor

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
@inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="/playouts/add">
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="playouts/add">
Add Playout
</MudButton>
<MudTable Hover="true"

4
ErsatzTV/Pages/PlexMediaSources.razor

@ -39,12 +39,12 @@ @@ -39,12 +39,12 @@
</MudTooltip>
<MudTooltip Text="Edit Libraries">
<MudIconButton Icon="@Icons.Material.Filled.VideoLibrary"
Link="@($"/media/sources/plex/{context.Id}/libraries")">
Link="@($"media/sources/plex/{context.Id}/libraries")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Edit Path Replacements">
<MudIconButton Icon="@Icons.Material.Filled.Folder"
Link="@($"/media/sources/plex/{context.Id}/paths")">
Link="@($"media/sources/plex/{context.Id}/paths")">
</MudIconButton>
</MudTooltip>
</div>

6
ErsatzTV/Pages/Schedules.razor

@ -34,12 +34,12 @@ @@ -34,12 +34,12 @@
<div style="align-items: center; display: flex;">
<MudTooltip Text="Edit Properties">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Link="@($"/schedules/{context.Id}")">
Link="@($"schedules/{context.Id}")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Edit Schedule Items">
<MudIconButton Icon="@Icons.Material.Filled.FormatListNumbered"
Link="@($"/schedules/{context.Id}/items")">
Link="@($"schedules/{context.Id}/items")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Delete Schedule">
@ -54,7 +54,7 @@ @@ -54,7 +54,7 @@
<MudTablePager/>
</PagerContent>
</MudTable>
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="/schedules/add" Class="mt-4">
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="schedules/add" Class="mt-4">
Add Schedule
</MudButton>

26
ErsatzTV/Pages/Search.razor

@ -110,7 +110,7 @@ @@ -110,7 +110,7 @@
@foreach (MovieCardViewModel card in _movies.Cards.OrderBy(m => m.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/movies/{card.MovieId}")"
Link="@($"media/movies/{card.MovieId}")"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(card, e))"
IsSelected="@IsSelected(card)"
@ -137,7 +137,7 @@ @@ -137,7 +137,7 @@
@foreach (TelevisionShowCardViewModel card in _shows.Cards.OrderBy(s => s.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/tv/shows/{card.TelevisionShowId}")"
Link="@($"media/tv/shows/{card.TelevisionShowId}")"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(card, e))"
IsSelected="@IsSelected(card)"
@ -164,7 +164,7 @@ @@ -164,7 +164,7 @@
@foreach (TelevisionSeasonCardViewModel card in _seasons.Cards.OrderBy(s => s.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/tv/seasons/{card.TelevisionSeasonId}")"
Link="@($"media/tv/seasons/{card.TelevisionSeasonId}")"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(card, e))"
IsSelected="@IsSelected(card)"
@ -192,7 +192,7 @@ @@ -192,7 +192,7 @@
{
<MediaCard Data="@card"
AddToCollectionClicked="@AddToCollection"
Link="@($"/media/tv/seasons/{card.SeasonId}#episode-{card.EpisodeId}")"
Link="@($"media/tv/seasons/{card.SeasonId}#episode-{card.EpisodeId}")"
Subtitle="@($"{card.ShowTitle} - S{card.Season} E{card.Episode}")"
SelectClicked="@(e => SelectClicked(card, e))"
IsSelected="@IsSelected(card)"
@ -219,7 +219,7 @@ @@ -219,7 +219,7 @@
@foreach (ArtistCardViewModel card in _artists.Cards.OrderBy(s => s.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/music/artists/{card.ArtistId}")"
Link="@($"media/music/artists/{card.ArtistId}")"
ArtworkKind="ArtworkKind.Thumbnail"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(card, e))"
@ -511,7 +511,7 @@ @@ -511,7 +511,7 @@
private string GetMoviesLink()
{
var uri = "/media/movies/page/1";
var uri = "media/movies/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -522,7 +522,7 @@ @@ -522,7 +522,7 @@
private string GetShowsLink()
{
var uri = "/media/tv/shows/page/1";
var uri = "media/tv/shows/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -533,7 +533,7 @@ @@ -533,7 +533,7 @@
private string GetSeasonsLink()
{
var uri = "/media/tv/seasons/page/1";
var uri = "media/tv/seasons/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -544,7 +544,7 @@ @@ -544,7 +544,7 @@
private string GetEpisodesLink()
{
var uri = "/media/tv/episodes/page/1";
var uri = "media/tv/episodes/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -555,7 +555,7 @@ @@ -555,7 +555,7 @@
private string GetArtistsLink()
{
var uri = "/media/music/artists/page/1";
var uri = "media/music/artists/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -566,7 +566,7 @@ @@ -566,7 +566,7 @@
private string GetMusicVideosLink()
{
var uri = "/media/music/videos/page/1";
var uri = "media/music/videos/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -577,7 +577,7 @@ @@ -577,7 +577,7 @@
private string GetOtherVideosLink()
{
var uri = "/media/other/videos/page/1";
var uri = "media/other/videos/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -588,7 +588,7 @@ @@ -588,7 +588,7 @@
private string GetSongsLink()
{
var uri = "/media/music/songs/page/1";
var uri = "media/music/songs/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

6
ErsatzTV/Pages/SongList.razor

@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
@if (_data.PageMap.IsSome)
{
<LetterBar PageMap="@_data.PageMap.ValueUnsafe()"
BaseUri="/media/music/songs"
BaseUri="media/music/songs"
Query="@_query"/>
}
@ -99,7 +99,7 @@ @@ -99,7 +99,7 @@
private void PrevPage()
{
string uri = $"/media/music/songs/page/{PageNumber - 1}";
string uri = $"media/music/songs/page/{PageNumber - 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -110,7 +110,7 @@ @@ -110,7 +110,7 @@
private void NextPage()
{
string uri = $"/media/music/songs/page/{PageNumber + 1}";
string uri = $"media/music/songs/page/{PageNumber + 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

12
ErsatzTV/Pages/TelevisionEpisodeList.razor

@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
}
else
{
<img src="@($"/artwork/fanart/{_season.FanArt}")" alt="fan art"/>
<img src="@($"artwork/fanart/{_season.FanArt}")" alt="fan art"/>
}
}
</MudContainer>
@ -41,11 +41,11 @@ @@ -41,11 +41,11 @@
{
<img class="mud-elevation-2 mr-6"
style="border-radius: 4px; flex-shrink: 0; max-height: 440px;"
src="@($"/artwork/posters/{_season.Poster}")" alt="season poster"/>
src="@($"artwork/posters/{_season.Poster}")" alt="season poster"/>
}
}
<div style="display: flex; flex-direction: column; height: 100%">
<MudLink Href="@($"/media/tv/shows/{_season.ShowId}")">
<MudLink Href="@($"media/tv/shows/{_season.ShowId}")">
<MudText Typo="Typo.h2" Class="media-item-title">@_season.Title</MudText>
</MudLink>
<MudText Typo="Typo.subtitle1" Class="media-item-subtitle mb-6 mud-text-secondary">@_season.Name</MudText>
@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
}
else
{
<MudCardMedia Image="@($"/artwork/thumbnails/{episode.Poster}")" Style="flex-grow: 1; height: 220px; width: 392px;"/>
<MudCardMedia Image="@($"artwork/thumbnails/{episode.Poster}")" Style="flex-grow: 1; height: 220px; width: 392px;"/>
}
@if (episode.State == MediaItemState.FileNotFound)
{
@ -219,7 +219,7 @@ @@ -219,7 +219,7 @@
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{
await _mediator.Send(new AddSeasonToCollection(collection.Id, SeasonId), _cts.Token);
_navigationManager.NavigateTo($"/media/collections/{collection.Id}");
_navigationManager.NavigateTo($"media/collections/{collection.Id}");
}
}
@ -234,7 +234,7 @@ @@ -234,7 +234,7 @@
if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule)
{
await _mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionSeason, null, null, null, SeasonId, PlaybackOrder.Shuffle, null, null, TailMode.None, null, GuideMode.Normal, null, null, null, null, null, null, null, null, null, null), _cts.Token);
_navigationManager.NavigateTo($"/schedules/{schedule.Id}/items");
_navigationManager.NavigateTo($"schedules/{schedule.Id}/items");
}
}

10
ErsatzTV/Pages/TelevisionSeasonList.razor

@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
}
else
{
<img src="@($"/artwork/fanart/{_show.FanArt}")" alt="fan art"/>
<img src="@($"artwork/fanart/{_show.FanArt}")" alt="fan art"/>
}
}
</MudContainer>
@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
{
<img class="mud-elevation-2 mr-6"
style="border-radius: 4px; flex-shrink: 0; max-height: 440px;"
src="@($"/artwork/posters/{_show.Poster}")" alt="movie poster"/>
src="@($"artwork/posters/{_show.Poster}")" alt="movie poster"/>
}
}
<div style="display: flex; flex-direction: column; height: 100%">
@ -144,7 +144,7 @@ @@ -144,7 +144,7 @@
@foreach (TelevisionSeasonCardViewModel card in _data.Cards)
{
<MediaCard Data="@card" Placeholder="@card.Placeholder"
Link="@($"/media/tv/seasons/{card.TelevisionSeasonId}")"
Link="@($"media/tv/seasons/{card.TelevisionSeasonId}")"
AddToCollectionClicked="@AddSeasonToCollection"/>
}
</MudContainer>
@ -215,7 +215,7 @@ @@ -215,7 +215,7 @@
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{
await _mediator.Send(new AddShowToCollection(collection.Id, ShowId), _cts.Token);
_navigationManager.NavigateTo($"/media/collections/{collection.Id}");
_navigationManager.NavigateTo($"media/collections/{collection.Id}");
}
}
@ -229,7 +229,7 @@ @@ -229,7 +229,7 @@
if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule)
{
await _mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionShow, null, null, null, ShowId, PlaybackOrder.Shuffle, null, null, TailMode.None, null, GuideMode.Normal, null, null, null, null, null, null, null, null, null, null), _cts.Token);
_navigationManager.NavigateTo($"/schedules/{schedule.Id}/items");
_navigationManager.NavigateTo($"schedules/{schedule.Id}/items");
}
}

8
ErsatzTV/Pages/TelevisionSeasonSearchResults.razor

@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid">
<FragmentLetterAnchor TCard="TelevisionSeasonCardViewModel" Cards="@_data.Cards">
<MediaCard Data="@context"
Link="@($"/media/tv/seasons/{context.TelevisionSeasonId}")"
Link="@($"media/tv/seasons/{context.TelevisionSeasonId}")"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(context, e))"
IsSelected="@IsSelected(context)"
@ -66,7 +66,7 @@ @@ -66,7 +66,7 @@
@if (_data.PageMap.IsSome)
{
<LetterBar PageMap="@_data.PageMap.ValueUnsafe()"
BaseUri="/media/tv/seasons"
BaseUri="media/tv/seasons"
Query="@_query"/>
}
@ -98,7 +98,7 @@ @@ -98,7 +98,7 @@
private void PrevPage()
{
string uri = $"/media/tv/seasons/page/{PageNumber - 1}";
string uri = $"media/tv/seasons/page/{PageNumber - 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -109,7 +109,7 @@ @@ -109,7 +109,7 @@
private void NextPage()
{
string uri = $"/media/tv/seasons/page/{PageNumber + 1}";
string uri = $"media/tv/seasons/page/{PageNumber + 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

8
ErsatzTV/Pages/TelevisionShowList.razor

@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid">
<FragmentLetterAnchor TCard="TelevisionShowCardViewModel" Cards="@_data.Cards">
<MediaCard Data="@context"
Link="@($"/media/tv/shows/{context.TelevisionShowId}")"
Link="@($"media/tv/shows/{context.TelevisionShowId}")"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(context, e))"
IsSelected="@IsSelected(context)"
@ -66,7 +66,7 @@ @@ -66,7 +66,7 @@
@if (_data.PageMap.IsSome)
{
<LetterBar PageMap="@_data.PageMap.ValueUnsafe()"
BaseUri="/media/tv/shows"
BaseUri="media/tv/shows"
Query="@_query"/>
}
@ -98,7 +98,7 @@ @@ -98,7 +98,7 @@
private void PrevPage()
{
string uri = $"/media/tv/shows/page/{PageNumber - 1}";
string uri = $"media/tv/shows/page/{PageNumber - 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -109,7 +109,7 @@ @@ -109,7 +109,7 @@
private void NextPage()
{
string uri = $"/media/tv/shows/page/{PageNumber + 1}";
string uri = $"media/tv/shows/page/{PageNumber + 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

2
ErsatzTV/Pages/TraktLists.razor

@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
<MudTooltip Text="Search Trakt List">
<MudIconButton Icon="@Icons.Material.Filled.Search"
Disabled="@_locker.IsTraktLocked()"
Link="@($"/search?query=trakt_list%3a{context.TraktId}")">
Link="@($"search?query=trakt_list%3a{context.TraktId}")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Match Trakt List Items">

26
ErsatzTV/Pages/Trash.razor

@ -107,7 +107,7 @@ @@ -107,7 +107,7 @@
@foreach (MovieCardViewModel card in _movies.Cards.OrderBy(m => m.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/movies/{card.MovieId}")"
Link="@($"media/movies/{card.MovieId}")"
DeleteClicked="@DeleteItemFromDatabase"
SelectColor="@Color.Error"
SelectClicked="@(e => SelectClicked(card, e))"
@ -135,7 +135,7 @@ @@ -135,7 +135,7 @@
@foreach (TelevisionShowCardViewModel card in _shows.Cards.OrderBy(s => s.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/tv/shows/{card.TelevisionShowId}")"
Link="@($"media/tv/shows/{card.TelevisionShowId}")"
DeleteClicked="@DeleteItemFromDatabase"
SelectColor="@Color.Error"
SelectClicked="@(e => SelectClicked(card, e))"
@ -163,7 +163,7 @@ @@ -163,7 +163,7 @@
@foreach (TelevisionSeasonCardViewModel card in _seasons.Cards.OrderBy(s => s.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/tv/seasons/{card.TelevisionSeasonId}")"
Link="@($"media/tv/seasons/{card.TelevisionSeasonId}")"
DeleteClicked="@DeleteItemFromDatabase"
SelectColor="@Color.Error"
SelectClicked="@(e => SelectClicked(card, e))"
@ -193,7 +193,7 @@ @@ -193,7 +193,7 @@
<MediaCard Data="@card"
DeleteClicked="@DeleteItemFromDatabase"
SelectColor="@Color.Error"
Link="@($"/media/tv/seasons/{card.SeasonId}#episode-{card.EpisodeId}")"
Link="@($"media/tv/seasons/{card.SeasonId}#episode-{card.EpisodeId}")"
Subtitle="@($"{card.ShowTitle} - S{card.Season} E{card.Episode}")"
SelectClicked="@(e => SelectClicked(card, e))"
IsSelected="@IsSelected(card)"
@ -220,7 +220,7 @@ @@ -220,7 +220,7 @@
@foreach (ArtistCardViewModel card in _artists.Cards.OrderBy(s => s.SortTitle))
{
<MediaCard Data="@card"
Link="@($"/media/music/artists/{card.ArtistId}")"
Link="@($"media/music/artists/{card.ArtistId}")"
ArtworkKind="ArtworkKind.Thumbnail"
DeleteClicked="@DeleteItemFromDatabase"
SelectColor="@Color.Error"
@ -368,7 +368,7 @@ @@ -368,7 +368,7 @@
private string GetMoviesLink()
{
var uri = "/media/movies/page/1";
var uri = "media/movies/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -379,7 +379,7 @@ @@ -379,7 +379,7 @@
private string GetShowsLink()
{
var uri = "/media/tv/shows/page/1";
var uri = "media/tv/shows/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -390,7 +390,7 @@ @@ -390,7 +390,7 @@
private string GetSeasonsLink()
{
var uri = "/media/tv/seasons/page/1";
var uri = "media/tv/seasons/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -401,7 +401,7 @@ @@ -401,7 +401,7 @@
private string GetEpisodesLink()
{
var uri = "/media/tv/episodes/page/1";
var uri = "media/tv/episodes/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -412,7 +412,7 @@ @@ -412,7 +412,7 @@
private string GetArtistsLink()
{
var uri = "/media/music/artists/page/1";
var uri = "media/music/artists/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -423,7 +423,7 @@ @@ -423,7 +423,7 @@
private string GetMusicVideosLink()
{
var uri = "/media/music/videos/page/1";
var uri = "media/music/videos/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -434,7 +434,7 @@ @@ -434,7 +434,7 @@
private string GetOtherVideosLink()
{
var uri = "/media/other/videos/page/1";
var uri = "media/other/videos/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
@ -445,7 +445,7 @@ @@ -445,7 +445,7 @@
private string GetSongsLink()
{
var uri = "/media/music/songs/page/1";
var uri = "media/music/songs/page/1";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();

4
ErsatzTV/Pages/Watermarks.razor

@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
<div style="align-items: center; display: flex;">
<MudTooltip Text="Edit Watermark">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Link="@($"/watermarks/{context.Id}")">
Link="@($"watermarks/{context.Id}")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Copy Watermark">
@ -65,7 +65,7 @@ @@ -65,7 +65,7 @@
</MudTd>
</RowTemplate>
</MudTable>
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="/watermarks/add" Class="mt-4">
<MudButton Variant="Variant.Filled" Color="Color.Primary" Link="watermarks/add" Class="mt-4">
Add Watermark
</MudButton>
</MudContainer>

2
ErsatzTV/Pages/_Host.cshtml

@ -29,7 +29,7 @@ @@ -29,7 +29,7 @@
$.ajax({
data: data,
type: 'POST',
url: `/media/collections/${collectionId}/items`
url: `media/collections/${collectionId}/items`
});
}
});

50
ErsatzTV/Shared/MainLayout.razor

@ -13,8 +13,8 @@ @@ -13,8 +13,8 @@
<MudLayout @onclick="@(() => _isOpen = false)">
<MudAppBar Elevation="1" Class="app-bar">
<div style="min-width: 240px">
<a href="/">
<img src="/images/ersatztv.png" alt="ErsatzTV"/>
<a href="">
<img src="images/ersatztv.png" alt="ErsatzTV"/>
</a>
</div>
<EditForm Model="@_dummyModel" OnSubmit="@(_ => PerformSearch())">
@ -61,8 +61,8 @@ @@ -61,8 +61,8 @@
</MudPopover>
</EditForm>
<MudSpacer/>
<MudLink Color="Color.Info" Href="/iptv/channels.m3u" Target="_blank" Underline="Underline.None">M3U</MudLink>
<MudLink Color="Color.Info" Href="/iptv/xmltv.xml" Target="_blank" Class="mx-4" Underline="Underline.None">XMLTV</MudLink>
<MudLink Color="Color.Info" Href="iptv/channels.m3u" Target="_blank" Underline="Underline.None">M3U</MudLink>
<MudLink Color="Color.Info" Href="iptv/xmltv.xml" Target="_blank" Class="mx-4" Underline="Underline.None">XMLTV</MudLink>
@* <MudLink Color="Color.Info" Href="/swagger" Target="_blank" Class="mr-4" Underline="Underline.None">API</MudLink> *@
<MudTooltip Text="Documentation">
<MudIconButton Icon="@Icons.Material.Filled.Help" Color="Color.Primary" Link="https://ersatztv.org" Target="_blank"/>
@ -76,33 +76,33 @@ @@ -76,33 +76,33 @@
</MudAppBar>
<MudDrawer Open="true" Elevation="2" ClipMode="DrawerClipMode.Always">
<MudNavMenu>
<MudNavLink Href="/channels">Channels</MudNavLink>
<MudNavLink Href="/ffmpeg">FFmpeg Profiles</MudNavLink>
<MudNavLink Href="/watermarks">Watermarks</MudNavLink>
<MudNavLink Href="channels">Channels</MudNavLink>
<MudNavLink Href="ffmpeg">FFmpeg Profiles</MudNavLink>
<MudNavLink Href="watermarks">Watermarks</MudNavLink>
<MudNavGroup Title="Media Sources" Expanded="true">
<MudNavLink Href="/media/sources/local">Local</MudNavLink>
<MudNavLink Href="/media/sources/emby">Emby</MudNavLink>
<MudNavLink Href="/media/sources/jellyfin">Jellyfin</MudNavLink>
<MudNavLink Href="/media/sources/plex">Plex</MudNavLink>
<MudNavLink Href="media/sources/local">Local</MudNavLink>
<MudNavLink Href="media/sources/emby">Emby</MudNavLink>
<MudNavLink Href="media/sources/jellyfin">Jellyfin</MudNavLink>
<MudNavLink Href="media/sources/plex">Plex</MudNavLink>
</MudNavGroup>
<MudNavGroup Title="Media" Expanded="true">
<MudNavLink Href="/media/libraries">Libraries</MudNavLink>
<MudNavLink Href="/media/trash">Trash</MudNavLink>
<MudNavLink Href="/media/tv/shows">TV Shows</MudNavLink>
<MudNavLink Href="/media/movies">Movies</MudNavLink>
<MudNavLink Href="/media/music/artists">Music</MudNavLink>
<MudNavLink Href="/media/other/videos">Other Videos</MudNavLink>
<MudNavLink Href="/media/music/songs">Songs</MudNavLink>
<MudNavLink Href="media/libraries">Libraries</MudNavLink>
<MudNavLink Href="media/trash">Trash</MudNavLink>
<MudNavLink Href="media/tv/shows">TV Shows</MudNavLink>
<MudNavLink Href="media/movies">Movies</MudNavLink>
<MudNavLink Href="media/music/artists">Music</MudNavLink>
<MudNavLink Href="media/other/videos">Other Videos</MudNavLink>
<MudNavLink Href="media/music/songs">Songs</MudNavLink>
</MudNavGroup>
<MudNavGroup Title="Lists" Expanded="true">
<MudNavLink Href="/media/collections">Collections</MudNavLink>
<MudNavLink Href="/media/trakt/lists">Trakt Lists</MudNavLink>
<MudNavLink Href="/media/filler/presets">Filler Presets</MudNavLink>
<MudNavLink Href="media/collections">Collections</MudNavLink>
<MudNavLink Href="media/trakt/lists">Trakt Lists</MudNavLink>
<MudNavLink Href="media/filler/presets">Filler Presets</MudNavLink>
</MudNavGroup>
<MudNavLink Href="/schedules">Schedules</MudNavLink>
<MudNavLink Href="/playouts">Playouts</MudNavLink>
<MudNavLink Href="/settings">Settings</MudNavLink>
<MudNavLink Href="/system/logs">Logs</MudNavLink>
<MudNavLink Href="schedules">Schedules</MudNavLink>
<MudNavLink Href="playouts">Playouts</MudNavLink>
<MudNavLink Href="settings">Settings</MudNavLink>
<MudNavLink Href="system/logs">Logs</MudNavLink>
<MudDivider Class="my-6" DividerType="DividerType.Middle"/>
<MudContainer Style="text-align: right" Class="mr-6">
<MudText Typo="Typo.body2">ErsatzTV Version</MudText>

2
ErsatzTV/Shared/MediaCard.razor

@ -153,7 +153,7 @@ @@ -153,7 +153,7 @@
return string.IsNullOrWhiteSpace(Data.Poster)
? "position: relative"
: $"position: relative; background-image: url(/artwork/{PathForArtwork()}/{Data.Poster}); background-size: cover; background-position: center";
: $"position: relative; background-image: url(artwork/{PathForArtwork()}/{Data.Poster}); background-size: cover; background-position: center";
}
private string PathForArtwork() => ArtworkKind switch

2
ErsatzTV/Shared/RemoteMediaSourceEditor.razor

@ -53,7 +53,7 @@ @@ -53,7 +53,7 @@
{
Either<BaseError, Unit> result = await SaveSecrets(_model);
result.Match(
_ => _navigationManager.NavigateTo($"/media/sources/{Name.ToLowerInvariant()}"),
_ => _navigationManager.NavigateTo($"media/sources/{Name.ToLowerInvariant()}"),
error =>
{
_snackbar.Add(error.Value, Severity.Error);

2
ErsatzTV/Shared/RemoteMediaSourceLibrariesEditor.razor

@ -114,7 +114,7 @@ @@ -114,7 +114,7 @@
}
}
_navigationManager.NavigateTo($"/media/sources/{Name.ToLowerInvariant()}");
_navigationManager.NavigateTo($"media/sources/{Name.ToLowerInvariant()}");
});
}

2
ErsatzTV/Shared/RemoteMediaSourcePathReplacementsEditor.razor

@ -139,7 +139,7 @@ @@ -139,7 +139,7 @@
_snackbar.Add($"Unexpected error saving path replacements: {error.Value}", Severity.Error);
_logger.LogError("Unexpected error saving path replacements: {Error}", error.Value);
},
() => _navigationManager.NavigateTo($"/media/sources/{Name.ToLowerInvariant()}"));
() => _navigationManager.NavigateTo($"media/sources/{Name.ToLowerInvariant()}"));
}
}

8
ErsatzTV/Shared/RemoteMediaSources.razor

@ -35,12 +35,12 @@ @@ -35,12 +35,12 @@
</MudTooltip>
<MudTooltip Text="Edit Libraries">
<MudIconButton Icon="@Icons.Material.Filled.VideoLibrary"
Link="@($"/media/sources/{Name.ToLowerInvariant()}/{context.Id}/libraries")">
Link="@($"media/sources/{Name.ToLowerInvariant()}/{context.Id}/libraries")">
</MudIconButton>
</MudTooltip>
<MudTooltip Text="Edit Path Replacements">
<MudIconButton Icon="@Icons.Material.Filled.Folder"
Link="@($"/media/sources/{Name.ToLowerInvariant()}/{context.Id}/paths")">
Link="@($"media/sources/{Name.ToLowerInvariant()}/{context.Id}/paths")">
</MudIconButton>
</MudTooltip>
</div>
@ -60,7 +60,7 @@ @@ -60,7 +60,7 @@
{
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
Link="@($"/media/sources/{Name.ToLowerInvariant()}/edit")"
Link="@($"media/sources/{Name.ToLowerInvariant()}/edit")"
Class="mt-4">
Connect @Name
</MudButton>
@ -70,7 +70,7 @@ @@ -70,7 +70,7 @@
{
<MudButton Variant="Variant.Filled"
Color="Color.Secondary"
Link="@($"/media/sources/{Name.ToLowerInvariant()}/edit")"
Link="@($"media/sources/{Name.ToLowerInvariant()}/edit")"
Class="ml-4 mt-4">
Fix @Name Connection
</MudButton>

10
ErsatzTV/Startup.cs

@ -59,6 +59,7 @@ using FluentValidation.AspNetCore; @@ -59,6 +59,7 @@ using FluentValidation.AspNetCore;
using Ganss.Xss;
using MediatR;
using MediatR.Courier.DependencyInjection;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
@ -87,6 +88,7 @@ public class Startup @@ -87,6 +88,7 @@ public class Startup
{
BugsnagConfiguration bugsnagConfig = Configuration.GetSection("Bugsnag").Get<BugsnagConfiguration>();
services.Configure<BugsnagConfiguration>(Configuration.GetSection("Bugsnag"));
services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.All; });
services.AddBugsnag(
configuration =>
@ -269,8 +271,16 @@ public class Startup @@ -269,8 +271,16 @@ public class Startup
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
string baseUrl = Environment.GetEnvironmentVariable("ETV_BASE_URL");
if (!string.IsNullOrWhiteSpace(baseUrl))
{
app.UsePathBase(baseUrl);
}
app.UseCors("AllowAll");
app.UseForwardedHeaders();
// app.UseHttpLogging();
// app.UseSerilogRequestLogging();
app.UseStaticFiles();

Loading…
Cancel
Save