Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ea8193bb3 | ||
|
|
8ad8680027 | ||
|
|
640044814c | ||
|
|
18b5313a53 |
+6
-1
@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.0.55-alpha] - 2021-09-03
|
||||
### Fixed
|
||||
- Fix all local library scanners to ignore dot underscore files (`._`)
|
||||
|
||||
## [0.0.54-alpha] - 2021-08-21
|
||||
### Added
|
||||
- Add `Shuffle In Order` playback order for multi-collections.
|
||||
@@ -546,7 +550,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Initial release to facilitate testing outside of Docker.
|
||||
|
||||
|
||||
[Unreleased]: https://github.com/jasongdove/ErsatzTV/compare/v0.0.54-alpha...HEAD
|
||||
[Unreleased]: https://github.com/jasongdove/ErsatzTV/compare/v0.0.55-alpha...HEAD
|
||||
[0.0.55-alpha]: https://github.com/jasongdove/ErsatzTV/compare/v0.0.54-alpha...v0.0.55-alpha
|
||||
[0.0.54-alpha]: https://github.com/jasongdove/ErsatzTV/compare/v0.0.53-alpha...v0.0.54-alpha
|
||||
[0.0.53-alpha]: https://github.com/jasongdove/ErsatzTV/compare/v0.0.52-alpha...v0.0.53-alpha
|
||||
[0.0.52-alpha]: https://github.com/jasongdove/ErsatzTV/compare/v0.0.51-alpha...v0.0.52-alpha
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="FluentAssertions" Version="6.0.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.1.0" />
|
||||
<PackageReference Include="LanguageExt.Core" Version="3.4.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||
|
||||
@@ -405,6 +405,48 @@ namespace ErsatzTV.Core.Tests.Metadata
|
||||
It.Is<Movie>(i => i.MediaVersions.Head().MediaFiles.Head().Path == moviePath)),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_Ignore_Dot_Underscore_Files(
|
||||
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))]
|
||||
string videoExtension)
|
||||
{
|
||||
string moviePath = Path.Combine(
|
||||
FakeRoot,
|
||||
Path.Combine("Movie (2020)", $"Movie (2020){videoExtension}"));
|
||||
|
||||
MovieFolderScanner service = GetService(
|
||||
new FakeFileEntry(moviePath) { LastWriteTime = DateTime.Now },
|
||||
new FakeFileEntry(
|
||||
Path.Combine(
|
||||
Path.GetDirectoryName(moviePath) ?? string.Empty,
|
||||
$"._Movie (2020){videoExtension}"))
|
||||
);
|
||||
var libraryPath = new LibraryPath
|
||||
{ Id = 1, Path = FakeRoot, LibraryFolders = new List<LibraryFolder>() };
|
||||
|
||||
Either<BaseError, Unit> result = await service.ScanFolder(
|
||||
libraryPath,
|
||||
FFprobePath,
|
||||
0,
|
||||
1);
|
||||
|
||||
result.IsRight.Should().BeTrue();
|
||||
|
||||
_movieRepository.Verify(x => x.GetOrAdd(It.IsAny<LibraryPath>(), It.IsAny<string>()), Times.Once);
|
||||
_movieRepository.Verify(x => x.GetOrAdd(libraryPath, moviePath), Times.Once);
|
||||
|
||||
_localStatisticsProvider.Verify(
|
||||
x => x.RefreshStatistics(
|
||||
FFprobePath,
|
||||
It.Is<Movie>(i => i.MediaVersions.Head().MediaFiles.Head().Path == moviePath)),
|
||||
Times.Once);
|
||||
|
||||
_localMetadataProvider.Verify(
|
||||
x => x.RefreshFallbackMetadata(
|
||||
It.Is<Movie>(i => i.MediaVersions.Head().MediaFiles.Head().Path == moviePath)),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_Ignore_Extra_Folders(
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace ErsatzTV.Core.Metadata
|
||||
|
||||
var allFiles = filesForEtag
|
||||
.Filter(f => VideoFileExtensions.Contains(Path.GetExtension(f)))
|
||||
.Filter(f => !Path.GetFileName(f).StartsWith("._"))
|
||||
.Filter(
|
||||
f => !ExtraFiles.Any(
|
||||
e => Path.GetFileNameWithoutExtension(f).EndsWith(e, StringComparison.OrdinalIgnoreCase)))
|
||||
@@ -157,6 +158,12 @@ namespace ErsatzTV.Core.Metadata
|
||||
List<int> ids = await _movieRepository.DeleteByPath(libraryPath, path);
|
||||
await _searchIndex.RemoveItems(ids);
|
||||
}
|
||||
else if (Path.GetFileName(path).StartsWith("._"))
|
||||
{
|
||||
_logger.LogInformation("Removing dot underscore file at {Path}", path);
|
||||
List<int> ids = await _movieRepository.DeleteByPath(libraryPath, path);
|
||||
await _searchIndex.RemoveItems(ids);
|
||||
}
|
||||
}
|
||||
|
||||
_searchIndex.Commit();
|
||||
|
||||
@@ -134,6 +134,12 @@ namespace ErsatzTV.Core.Metadata
|
||||
List<int> musicVideoIds = await _musicVideoRepository.DeleteByPath(libraryPath, path);
|
||||
await _searchIndex.RemoveItems(musicVideoIds);
|
||||
}
|
||||
else if (Path.GetFileName(path).StartsWith("._"))
|
||||
{
|
||||
_logger.LogInformation("Removing dot underscore file at {Path}", path);
|
||||
List<int> musicVideoIds = await _musicVideoRepository.DeleteByPath(libraryPath, path);
|
||||
await _searchIndex.RemoveItems(musicVideoIds);
|
||||
}
|
||||
}
|
||||
|
||||
List<int> artistIds = await _artistRepository.DeleteEmptyArtists(libraryPath);
|
||||
@@ -238,6 +244,7 @@ namespace ErsatzTV.Core.Metadata
|
||||
|
||||
var allFiles = _localFileSystem.ListFiles(musicVideoFolder)
|
||||
.Filter(f => VideoFileExtensions.Contains(Path.GetExtension(f)))
|
||||
.Filter(f => !Path.GetFileName(f).StartsWith("._"))
|
||||
.ToList();
|
||||
|
||||
foreach (string subdirectory in _localFileSystem.ListSubdirectories(musicVideoFolder)
|
||||
|
||||
@@ -124,6 +124,11 @@ namespace ErsatzTV.Core.Metadata
|
||||
_logger.LogInformation("Removing missing episode at {Path}", path);
|
||||
await _televisionRepository.DeleteByPath(libraryPath, path);
|
||||
}
|
||||
else if (Path.GetFileName(path).StartsWith("._"))
|
||||
{
|
||||
_logger.LogInformation("Removing dot underscore file at {Path}", path);
|
||||
await _televisionRepository.DeleteByPath(libraryPath, path);
|
||||
}
|
||||
}
|
||||
|
||||
await _televisionRepository.DeleteEmptySeasons(libraryPath);
|
||||
@@ -201,7 +206,9 @@ namespace ErsatzTV.Core.Metadata
|
||||
string seasonPath)
|
||||
{
|
||||
foreach (string file in _localFileSystem.ListFiles(seasonPath)
|
||||
.Filter(f => VideoFileExtensions.Contains(Path.GetExtension(f))).OrderBy(identity))
|
||||
.Filter(f => VideoFileExtensions.Contains(Path.GetExtension(f)))
|
||||
.Filter(f => !Path.GetFileName(f).StartsWith("._"))
|
||||
.OrderBy(identity))
|
||||
{
|
||||
// TODO: figure out how to rebuild playlists
|
||||
Either<BaseError, Episode> maybeEpisode = await _televisionRepository
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.1.2" />
|
||||
<PackageReference Include="FluentValidation" Version="10.3.1" />
|
||||
<PackageReference Include="FluentValidation.AspNetCore" Version="10.3.1" />
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.1.5" />
|
||||
<PackageReference Include="FluentValidation" Version="10.3.3" />
|
||||
<PackageReference Include="FluentValidation.AspNetCore" Version="10.3.3" />
|
||||
<PackageReference Include="HtmlSanitizer" Version="6.0.441" />
|
||||
<PackageReference Include="LanguageExt.Core" Version="3.4.15" />
|
||||
<PackageReference Include="Markdig" Version="0.25.0" />
|
||||
<PackageReference Include="Markdig" Version="0.26.0" />
|
||||
<PackageReference Include="MediatR.Courier.DependencyInjection" Version="3.0.1" />
|
||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.9" />
|
||||
@@ -34,7 +34,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MudBlazor" Version="5.1.1" />
|
||||
<PackageReference Include="MudBlazor" Version="5.1.2" />
|
||||
<PackageReference Include="NaturalSort.Extension" Version="3.1.0" />
|
||||
<PackageReference Include="PPioli.FluentValidation.Blazor" Version="5.0.0" />
|
||||
<PackageReference Include="Refit.HttpClientFactory" Version="6.0.94" />
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<MudTable Hover="true" Items="_ffmpegProfiles">
|
||||
<ToolBarContent>
|
||||
<MudText Typo="Typo.h6">FFmpeg Profiles</MudText>
|
||||
<MudToolBarSpacer></MudToolBarSpacer>
|
||||
<MudSpacer/>
|
||||
<MudText Color="Color.Tertiary">Colored settings will be normalized</MudText>
|
||||
</ToolBarContent>
|
||||
<ColGroup>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
Class="search-bar">
|
||||
</MudTextField>
|
||||
</EditForm>
|
||||
<MudAppBarSpacer/>
|
||||
<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="/swagger" Target="_blank" Class="mr-4" Underline="Underline.None">API</MudLink> *@
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
|
||||
.release-notes h3 { margin-top: 20px; }
|
||||
|
||||
.mud-table-container { overflow-x: unset; }
|
||||
.mud-table-container { overflow-x: unset; overflow-y: unset; }
|
||||
|
||||
#blazor-error-ui { color: black; }
|
||||
#blazor-error-ui a { color: unset; }
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||

|
||||
|
||||
**ErsatzTV** is pre-alpha software for configuring and streaming custom live channels using your media library. The software is currently unstable and under active development.
|
||||
**ErsatzTV** is alpha software for configuring and streaming custom live channels using your media library. The software is currently unstable and under active development.
|
||||
|
||||
Want to join the community or have a question? Join us on [Discord](https://discord.gg/hHaJm3yGy6).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user