mirror of https://github.com/ErsatzTV/ErsatzTV.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
10 KiB
292 lines
10 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.IO; |
|
using System.Linq; |
|
using System.Text.RegularExpressions; |
|
using ErsatzTV.Core.Domain; |
|
using ErsatzTV.Core.Interfaces.Metadata; |
|
using LanguageExt; |
|
using static LanguageExt.Prelude; |
|
|
|
namespace ErsatzTV.Core.Metadata |
|
{ |
|
public class FallbackMetadataProvider : IFallbackMetadataProvider |
|
{ |
|
public ShowMetadata GetFallbackMetadataForShow(string showFolder) |
|
{ |
|
string fileName = Path.GetFileName(showFolder); |
|
var metadata = new ShowMetadata |
|
{ |
|
MetadataKind = MetadataKind.Fallback, |
|
Title = fileName ?? showFolder, |
|
Genres = new List<Genre>(), |
|
Tags = new List<Tag>(), |
|
Studios = new List<Studio>(), |
|
Actors = new List<Actor>() |
|
}; |
|
return GetTelevisionShowMetadata(fileName, metadata); |
|
} |
|
|
|
public ArtistMetadata GetFallbackMetadataForArtist(string artistFolder) |
|
{ |
|
string fileName = Path.GetFileName(artistFolder); |
|
return new ArtistMetadata |
|
{ MetadataKind = MetadataKind.Fallback, Title = fileName ?? artistFolder }; |
|
} |
|
|
|
public List<EpisodeMetadata> GetFallbackMetadata(Episode episode) |
|
{ |
|
string path = episode.MediaVersions.Head().MediaFiles.Head().Path; |
|
string fileName = Path.GetFileName(path); |
|
var baseMetadata = new EpisodeMetadata |
|
{ |
|
MetadataKind = MetadataKind.Fallback, |
|
Title = Path.GetFileNameWithoutExtension(path) ?? path, |
|
DateAdded = DateTime.UtcNow, |
|
EpisodeNumber = 0, |
|
Actors = new List<Actor>(), |
|
Artwork = new List<Artwork>(), |
|
Directors = new List<Director>(), |
|
Genres = new List<Genre>(), |
|
Guids = new List<MetadataGuid>(), |
|
Studios = new List<Studio>(), |
|
Tags = new List<Tag>(), |
|
Writers = new List<Writer>() |
|
}; |
|
return fileName != null |
|
? GetEpisodeMetadata(fileName, baseMetadata) |
|
: new List<EpisodeMetadata> { baseMetadata }; |
|
} |
|
|
|
public MovieMetadata GetFallbackMetadata(Movie movie) |
|
{ |
|
string path = movie.MediaVersions.Head().MediaFiles.Head().Path; |
|
string fileName = Path.GetFileName(path); |
|
var metadata = new MovieMetadata |
|
{ |
|
MetadataKind = MetadataKind.Fallback, |
|
Title = Path.GetFileNameWithoutExtension(path) ?? path, |
|
Genres = new List<Genre>(), |
|
Tags = new List<Tag>(), |
|
Studios = new List<Studio>(), |
|
Actors = new List<Actor>(), |
|
Directors = new List<Director>(), |
|
Writers = new List<Writer>() |
|
}; |
|
|
|
return fileName != null ? GetMovieMetadata(fileName, metadata) : metadata; |
|
} |
|
|
|
public Option<MusicVideoMetadata> GetFallbackMetadata(MusicVideo musicVideo) |
|
{ |
|
string path = musicVideo.MediaVersions.Head().MediaFiles.Head().Path; |
|
string fileName = Path.GetFileName(path); |
|
var metadata = new MusicVideoMetadata |
|
{ |
|
MetadataKind = MetadataKind.Fallback, |
|
Title = fileName ?? path |
|
}; |
|
|
|
return GetMusicVideoMetadata(fileName, metadata); |
|
} |
|
|
|
public Option<OtherVideoMetadata> GetFallbackMetadata(OtherVideo otherVideo) |
|
{ |
|
string path = otherVideo.MediaVersions.Head().MediaFiles.Head().Path; |
|
string fileName = Path.GetFileNameWithoutExtension(path); |
|
var metadata = new OtherVideoMetadata |
|
{ |
|
MetadataKind = MetadataKind.Fallback, |
|
Title = fileName ?? path, |
|
OtherVideo = otherVideo |
|
}; |
|
|
|
return GetOtherVideoMetadata(path, metadata); |
|
} |
|
|
|
public string GetSortTitle(string title) |
|
{ |
|
if (string.IsNullOrWhiteSpace(title)) |
|
{ |
|
return title; |
|
} |
|
|
|
if (title.StartsWith("the ", StringComparison.OrdinalIgnoreCase)) |
|
{ |
|
return title.Substring(4); |
|
} |
|
|
|
if (title.StartsWith("a ", StringComparison.OrdinalIgnoreCase)) |
|
{ |
|
return title.Substring(2); |
|
} |
|
|
|
if (title.StartsWith("an ", StringComparison.OrdinalIgnoreCase)) |
|
{ |
|
return title.Substring(3); |
|
} |
|
|
|
if (title.StartsWith("Æ")) |
|
{ |
|
return title.Replace("Æ", "E"); |
|
} |
|
|
|
return title; |
|
} |
|
|
|
private static List<EpisodeMetadata> GetEpisodeMetadata(string fileName, EpisodeMetadata baseMetadata) |
|
{ |
|
var result = new List<EpisodeMetadata>(); |
|
|
|
try |
|
{ |
|
const string PATTERN = @"[sS]\d+[eE]([e\-\d{1,2}]+)"; |
|
MatchCollection matches = Regex.Matches(fileName, PATTERN); |
|
if (matches.Count > 0) |
|
{ |
|
foreach (Match match in matches) |
|
{ |
|
string[] split = match.Groups[1].Value.Replace('e', '-').Split('-'); |
|
foreach (string ep in split) |
|
{ |
|
if (!int.TryParse(ep, out int episodeNumber)) |
|
{ |
|
continue; |
|
} |
|
|
|
var metadata = new EpisodeMetadata |
|
{ |
|
MetadataKind = MetadataKind.Fallback, |
|
EpisodeNumber = episodeNumber, |
|
DateAdded = baseMetadata.DateAdded, |
|
DateUpdated = baseMetadata.DateAdded, |
|
Title = baseMetadata.Title, |
|
Actors = new List<Actor>(), |
|
Artwork = new List<Artwork>(), |
|
Directors = new List<Director>(), |
|
Genres = new List<Genre>(), |
|
Guids = new List<MetadataGuid>(), |
|
Studios = new List<Studio>(), |
|
Tags = new List<Tag>(), |
|
Writers = new List<Writer>() |
|
}; |
|
|
|
result.Add(metadata); |
|
} |
|
} |
|
|
|
return result; |
|
} |
|
} |
|
catch (Exception) |
|
{ |
|
// ignored |
|
} |
|
|
|
return result; |
|
} |
|
|
|
private MovieMetadata GetMovieMetadata(string fileName, MovieMetadata metadata) |
|
{ |
|
try |
|
{ |
|
const string PATTERN = @"^(.*?)[.\(](\d{4})[.\)].*\.\w+$"; |
|
Match match = Regex.Match(fileName, PATTERN); |
|
if (match.Success) |
|
{ |
|
metadata.Title = match.Groups[1].Value.Trim(); |
|
metadata.Year = int.Parse(match.Groups[2].Value); |
|
metadata.ReleaseDate = new DateTime(int.Parse(match.Groups[2].Value), 1, 1); |
|
metadata.DateUpdated = DateTime.UtcNow; |
|
} |
|
} |
|
catch (Exception) |
|
{ |
|
// ignored |
|
} |
|
|
|
return metadata; |
|
} |
|
|
|
private Option<MusicVideoMetadata> GetMusicVideoMetadata(string fileName, MusicVideoMetadata metadata) |
|
{ |
|
try |
|
{ |
|
const string PATTERN = @"^(.*?) - (.*?).\w+$"; |
|
Match match = Regex.Match(fileName, PATTERN); |
|
metadata.Title = match.Success |
|
? match.Groups[2].Value.Trim() |
|
: Path.GetFileNameWithoutExtension(fileName); |
|
metadata.Genres = new List<Genre>(); |
|
metadata.Tags = new List<Tag>(); |
|
metadata.Studios = new List<Studio>(); |
|
metadata.DateUpdated = DateTime.UtcNow; |
|
|
|
return metadata; |
|
} |
|
catch (Exception) |
|
{ |
|
return None; |
|
} |
|
} |
|
|
|
private Option<OtherVideoMetadata> GetOtherVideoMetadata(string path, OtherVideoMetadata metadata) |
|
{ |
|
try |
|
{ |
|
string folder = Path.GetDirectoryName(path); |
|
if (folder == null) |
|
{ |
|
return None; |
|
} |
|
|
|
string libraryPath = metadata.OtherVideo.LibraryPath.Path; |
|
string parent = Optional(Directory.GetParent(libraryPath)).Match( |
|
di => di.FullName, |
|
() => libraryPath); |
|
|
|
string diff = Path.GetRelativePath(parent, folder); |
|
|
|
var tags = diff.Split(Path.DirectorySeparatorChar) |
|
.Map(t => new Tag { Name = t }) |
|
.ToList(); |
|
|
|
metadata.Artwork = new List<Artwork>(); |
|
metadata.Actors = new List<Actor>(); |
|
metadata.Genres = new List<Genre>(); |
|
metadata.Tags = tags; |
|
metadata.Studios = new List<Studio>(); |
|
metadata.DateUpdated = DateTime.UtcNow; |
|
metadata.OriginalTitle = Path.GetRelativePath(libraryPath, path); |
|
|
|
return metadata; |
|
} |
|
catch (Exception) |
|
{ |
|
return None; |
|
} |
|
} |
|
|
|
private ShowMetadata GetTelevisionShowMetadata(string fileName, ShowMetadata metadata) |
|
{ |
|
try |
|
{ |
|
const string PATTERN = @"^(.*?)[\s.]+?[.\(](\d{4})[.\)].*$"; |
|
Match match = Regex.Match(fileName, PATTERN); |
|
if (match.Success) |
|
{ |
|
metadata.Title = match.Groups[1].Value; |
|
metadata.Year = int.Parse(match.Groups[2].Value); |
|
metadata.ReleaseDate = new DateTime(int.Parse(match.Groups[2].Value), 1, 1); |
|
metadata.DateUpdated = DateTime.UtcNow; |
|
} |
|
} |
|
catch (Exception) |
|
{ |
|
// ignored |
|
} |
|
|
|
return metadata; |
|
} |
|
} |
|
}
|
|
|