Merge remote-tracking branch 'upstream/master' into integration-tests

pull/2945/head
Mark Monteiro 4 years ago
commit 1c06111497

@ -1,59 +0,0 @@
VERSION := $(shell sed -ne '/^Version:/s/.* *//p' \
deployment/fedora-package-x64/pkg-src/jellyfin.spec)
deployment/fedora-package-x64/pkg-src/jellyfin-web-$(VERSION).tar.gz:
curl -f -L -o deployment/fedora-package-x64/pkg-src/jellyfin-web-$(VERSION).tar.gz \
https://github.com/jellyfin/jellyfin-web/archive/v$(VERSION).tar.gz \
|| curl -f -L -o deployment/fedora-package-x64/pkg-src/jellyfin-web-$(VERSION).tar.gz \
https://github.com/jellyfin/jellyfin-web/archive/master.tar.gz \
srpm: deployment/fedora-package-x64/pkg-src/jellyfin-web-$(VERSION).tar.gz
cd deployment/fedora-package-x64; \
SOURCE_DIR=../.. \
WORKDIR="$${PWD}"; \
package_temporary_dir="$${WORKDIR}/pkg-dist-tmp"; \
pkg_src_dir="$${WORKDIR}/pkg-src"; \
GNU_TAR=1; \
tar \
--transform "s,^\.,jellyfin-$(VERSION)," \
--exclude='.git*' \
--exclude='**/.git' \
--exclude='**/.hg' \
--exclude='**/.vs' \
--exclude='**/.vscode' \
--exclude='deployment' \
--exclude='**/bin' \
--exclude='**/obj' \
--exclude='**/.nuget' \
--exclude='*.deb' \
--exclude='*.rpm' \
-czf "pkg-src/jellyfin-$(VERSION).tar.gz" \
-C $${SOURCE_DIR} ./ || GNU_TAR=0; \
if [ $${GNU_TAR} -eq 0 ]; then \
package_temporary_dir="$$(mktemp -d)"; \
mkdir -p "$${package_temporary_dir}/jellyfin"; \
tar \
--exclude='.git*' \
--exclude='**/.git' \
--exclude='**/.hg' \
--exclude='**/.vs' \
--exclude='**/.vscode' \
--exclude='deployment' \
--exclude='**/bin' \
--exclude='**/obj' \
--exclude='**/.nuget' \
--exclude='*.deb' \
--exclude='*.rpm' \
-czf "$${package_temporary_dir}/jellyfin/jellyfin-$(VERSION).tar.gz" \
-C $${SOURCE_DIR} ./; \
mkdir -p "$${package_temporary_dir}/jellyfin-$(VERSION)"; \
tar -xzf "$${package_temporary_dir}/jellyfin/jellyfin-$(VERSION).tar.gz" \
-C "$${package_temporary_dir}/jellyfin-$(VERSION); \
rm -f "$${package_temporary_dir}/jellyfin/jellyfin-$(VERSION).tar.gz"; \
tar -czf "$${SOURCE_DIR}/SOURCES/pkg-src/jellyfin-$(VERSION).tar.gz" \
-C "$${package_temporary_dir}" "jellyfin-$(VERSION); \
rm -rf $${package_temporary_dir}; \
fi; \
rpmbuild -bs pkg-src/jellyfin.spec \
--define "_sourcedir $$PWD/pkg-src/" \
--define "_srcrpmdir $(outdir)"

@ -0,0 +1 @@
../fedora/Makefile

@ -0,0 +1,3 @@
# Joshua must review all changes to deployment and build.sh
deployment/* @joshuaboniface
build.sh @joshuaboniface

19
.gitignore vendored

@ -246,14 +246,14 @@ pip-log.txt
#########################
# Artifacts for debian-x64
deployment/debian-package-x64/pkg-src/.debhelper/
deployment/debian-package-x64/pkg-src/*.debhelper
deployment/debian-package-x64/pkg-src/debhelper-build-stamp
deployment/debian-package-x64/pkg-src/files
deployment/debian-package-x64/pkg-src/jellyfin.substvars
deployment/debian-package-x64/pkg-src/jellyfin/
debian/.debhelper/
debian/*.debhelper
debian/debhelper-build-stamp
debian/files
debian/jellyfin.substvars
debian/jellyfin/
# Don't ignore the debian/bin folder
!deployment/debian-package-x64/pkg-src/bin/
!debian/bin/
deployment/**/dist/
deployment/**/pkg-dist/
@ -273,3 +273,8 @@ dist
# BenchmarkDotNet artifacts
BenchmarkDotNet.Artifacts
# Ignore web artifacts from native builds
web/
web-src.*
MediaBrowser.WebDashboard/jellyfin-web/

@ -425,57 +425,99 @@ namespace Emby.Dlna.Didl
}
}
if (item is Episode episode && context is Season season)
return item is Episode episode
? GetEpisodeDisplayName(episode, context)
: item.Name;
}
/// <summary>
/// Gets episode display name appropriate for the given context.
/// </summary>
/// <remarks>
/// If context is a season, this will return a string containing just episode number and name.
/// Otherwise the result will include series nams and season number.
/// </remarks>
/// <param name="episode">The episode.</param>
/// <param name="context">Current context.</param>
/// <returns>Formatted name of the episode.</returns>
private string GetEpisodeDisplayName(Episode episode, BaseItem context)
{
string[] components;
if (context is Season season)
{
// This is a special embedded within a season
if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0
if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value == 0
&& season.IndexNumber.HasValue && season.IndexNumber.Value != 0)
{
return string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("ValueSpecialEpisodeName"),
item.Name);
episode.Name);
}
if (item.IndexNumber.HasValue)
{
var number = item.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
// inside a season use simple format (ex. '12 - Episode Name')
var epNumberName = GetEpisodeIndexFullName(episode);
components = new[] { epNumberName, episode.Name };
}
else
{
// outside a season include series and season details (ex. 'TV Show - S05E11 - Episode Name')
var epNumberName = GetEpisodeNumberDisplayName(episode);
components = new[] { episode.SeriesName, epNumberName, episode.Name };
}
if (episode.IndexNumberEnd.HasValue)
{
number += "-" + episode.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture);
}
return string.Join(" - ", components.Where(NotNullOrWhiteSpace));
}
return number + " - " + item.Name;
}
}
else if (item is Episode ep)
/// <summary>
/// Gets complete episode number.
/// </summary>
/// <param name="episode">The episode.</param>
/// <returns>For single episodes returns just the number. For double episodes - current and ending numbers.</returns>
private string GetEpisodeIndexFullName(Episode episode)
{
var name = string.Empty;
if (episode.IndexNumber.HasValue)
{
var parent = ep.GetParent();
var name = parent.Name + " - ";
name += episode.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
if (ep.ParentIndexNumber.HasValue)
{
name += "S" + ep.ParentIndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
}
else if (!item.IndexNumber.HasValue)
if (episode.IndexNumberEnd.HasValue)
{
return name + " - " + item.Name;
name += "-" + episode.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture);
}
}
name += "E" + ep.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
if (ep.IndexNumberEnd.HasValue)
{
name += "-" + ep.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture);
}
return name;
}
name += " - " + item.Name;
return name;
/// <summary>
/// Gets episode number formatted as 'S##E##'.
/// </summary>
/// <param name="episode">The episode.</param>
/// <returns>Formatted episode number.</returns>
private string GetEpisodeNumberDisplayName(Episode episode)
{
var name = string.Empty;
var seasonNumber = episode.Season?.IndexNumber;
if (seasonNumber.HasValue)
{
name = "S" + seasonNumber.Value.ToString("00", CultureInfo.InvariantCulture);
}
var indexName = GetEpisodeIndexFullName(episode);
if (!string.IsNullOrWhiteSpace(indexName))
{
name += "E" + indexName;
}
return item.Name;
return name;
}
private bool NotNullOrWhiteSpace(string s) => !string.IsNullOrWhiteSpace(s);
private void AddAudioResource(XmlWriter writer, BaseItem audio, string deviceId, Filter filter, StreamInfo streamInfo = null)
{
writer.WriteStartElement(string.Empty, "res", NS_DIDL);

@ -12,7 +12,7 @@ namespace Emby.Dlna.Profiles
{
Name = "Generic Device";
ProtocolInfo = "http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*";
ProtocolInfo = "http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*";
Manufacturer = "Jellyfin";
ModelDescription = "UPnP/AV 1.0 Compliant Media Server";

@ -21,7 +21,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -26,7 +26,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -27,7 +27,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
<RequiresPlainVideoItems>true</RequiresPlainVideoItems>
<RequiresPlainFolders>true</RequiresPlainFolders>

@ -27,7 +27,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -25,7 +25,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -27,7 +27,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -27,7 +27,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -28,7 +28,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -21,7 +21,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -27,7 +27,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -27,7 +27,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>true</RequiresPlainVideoItems>
<RequiresPlainFolders>true</RequiresPlainFolders>

@ -29,7 +29,7 @@
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -29,7 +29,7 @@
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -29,7 +29,7 @@
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -29,7 +29,7 @@
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -29,7 +29,7 @@
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -29,7 +29,7 @@
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -28,7 +28,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>5</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -28,7 +28,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>40</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -27,7 +27,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*</ProtocolInfo>
<ProtocolInfo>http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*:image/jpeg:*,http-get:*:image/png:*,http-get:*:image/gif:*,http-get:*:image/tiff:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>

@ -1,9 +1,9 @@
#nullable enable
#pragma warning disable CS1591
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Emby.Naming.Common;
@ -21,8 +21,7 @@ namespace Emby.Naming.Audio
public bool IsMultiPart(string path)
{
var filename = Path.GetFileName(path);
if (string.IsNullOrEmpty(filename))
if (filename.Length == 0)
{
return false;
}
@ -39,18 +38,22 @@ namespace Emby.Naming.Audio
filename = filename.Replace(')', ' ');
filename = Regex.Replace(filename, @"\s+", " ");
filename = filename.TrimStart();
ReadOnlySpan<char> trimmedFilename = filename.TrimStart();
foreach (var prefix in _options.AlbumStackingPrefixes)
{
if (filename.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) != 0)
if (!trimmedFilename.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
continue;
}
var tmp = filename.Substring(prefix.Length);
var tmp = trimmedFilename.Slice(prefix.Length).Trim();
tmp = tmp.Trim().Split(' ').FirstOrDefault() ?? string.Empty;
int index = tmp.IndexOf(' ');
if (index != -1)
{
tmp = tmp.Slice(0, index);
}
if (int.TryParse(tmp, NumberStyles.Integer, CultureInfo.InvariantCulture, out _))
{

@ -1,3 +1,4 @@
#nullable enable
#pragma warning disable CS1591
using System;
@ -11,7 +12,7 @@ namespace Emby.Naming.Audio
{
public static bool IsAudioFile(string path, NamingOptions options)
{
var extension = Path.GetExtension(path) ?? string.Empty;
var extension = Path.GetExtension(path);
return options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
}
}

@ -23,11 +23,6 @@ namespace Emby.Naming.Common
{
}
public EpisodeExpression()
: this(null)
{
}
public string Expression
{
get => _expression;
@ -48,6 +43,6 @@ namespace Emby.Naming.Common
public string[] DateTimeFormats { get; set; }
public Regex Regex => _regex ?? (_regex = new Regex(Expression, RegexOptions.IgnoreCase | RegexOptions.Compiled));
public Regex Regex => _regex ??= new Regex(Expression, RegexOptions.IgnoreCase | RegexOptions.Compiled);
}
}

@ -1,3 +1,4 @@
#nullable enable
#pragma warning disable CS1591
using System;
@ -16,11 +17,11 @@ namespace Emby.Naming.Subtitles
_options = options;
}
public SubtitleInfo ParseFile(string path)
public SubtitleInfo? ParseFile(string path)
{
if (string.IsNullOrEmpty(path))
if (path.Length == 0)
{
throw new ArgumentNullException(nameof(path));
throw new ArgumentException("File path can't be empty.", nameof(path));
}
var extension = Path.GetExtension(path);
@ -52,11 +53,6 @@ namespace Emby.Naming.Subtitles
private string[] GetFlags(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentNullException(nameof(path));
}
// Note: the tags need be be surrounded be either a space ( ), hyphen -, dot . or underscore _.
var file = Path.GetFileName(path);

@ -143,7 +143,7 @@ namespace Emby.Notifications
var notification = new NotificationRequest
{
Description = "Please see jellyfin.media for details.",
Description = "Please see jellyfin.org for details.",
NotificationType = type,
Name = _localization.GetLocalizedString("NewVersionIsAvailable")
};

@ -137,7 +137,7 @@ namespace Emby.Server.Implementations.Activity
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"),
e.Provider,
Emby.Notifications.NotificationEntryPoint.GetItemName(e.Item)),
Notifications.NotificationEntryPoint.GetItemName(e.Item)),
Type = "SubtitleDownloadFailure",
ItemId = e.Item.Id.ToString("N", CultureInfo.InvariantCulture),
ShortOverview = e.Exception.Message
@ -265,31 +265,20 @@ namespace Emby.Server.Implementations.Activity
private void OnSessionEnded(object sender, SessionEventArgs e)
{
string name;
var session = e.SessionInfo;
if (string.IsNullOrEmpty(session.UserName))
{
name = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("DeviceOfflineWithName"),
session.DeviceName);
// Causing too much spam for now
return;
}
else
CreateLogEntry(new ActivityLogEntry
{
name = string.Format(
Name = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserOfflineFromDevice"),
session.UserName,
session.DeviceName);
}
CreateLogEntry(new ActivityLogEntry
{
Name = name,
session.DeviceName),
Type = "SessionEnded",
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
@ -388,31 +377,20 @@ namespace Emby.Server.Implementations.Activity
private void OnSessionStarted(object sender, SessionEventArgs e)
{
string name;
var session = e.SessionInfo;
if (string.IsNullOrEmpty(session.UserName))
{
name = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("DeviceOnlineWithName"),
session.DeviceName);
// Causing too much spam for now
return;
}
else
CreateLogEntry(new ActivityLogEntry
{
name = string.Format(
Name = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserOnlineFromDevice"),
session.UserName,
session.DeviceName);
}
CreateLogEntry(new ActivityLogEntry
{
Name = name,
session.DeviceName),
Type = "SessionStarted",
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
@ -580,7 +558,7 @@ namespace Emby.Server.Implementations.Activity
{
int years = days / DaysInYear;
values.Add(CreateValueString(years, "year"));
days = days % DaysInYear;
days %= DaysInYear;
}
// Number of months
@ -588,7 +566,7 @@ namespace Emby.Server.Implementations.Activity
{
int months = days / DaysInMonth;
values.Add(CreateValueString(months, "month"));
days = days % DaysInMonth;
days %= DaysInMonth;
}
// Number of days

@ -1,25 +1,31 @@
#pragma warning disable CS1591
using System;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Querying;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Activity
{
/// <summary>
/// The activity log manager.
/// </summary>
public class ActivityManager : IActivityManager
{
private readonly IActivityRepository _repo;
private readonly IUserManager _userManager;
/// <summary>
/// Initializes a new instance of the <see cref="ActivityManager"/> class.
/// </summary>
/// <param name="repo">The activity repository.</param>
/// <param name="userManager">The user manager.</param>
public ActivityManager(IActivityRepository repo, IUserManager userManager)
{
_repo = repo;
_userManager = userManager;
}
/// <inheritdoc />
public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
public void Create(ActivityLogEntry entry)
@ -31,6 +37,7 @@ namespace Emby.Server.Implementations.Activity
EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(entry));
}
/// <inheritdoc />
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
{
var result = _repo.GetActivityLogEntries(minDate, hasUserId, startIndex, limit);
@ -54,6 +61,7 @@ namespace Emby.Server.Implementations.Activity
return result;
}
/// <inheritdoc />
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit)
{
return GetActivityLogEntries(minDate, null, startIndex, limit);

@ -1,5 +1,3 @@
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Globalization;
@ -15,12 +13,21 @@ using SQLitePCL.pretty;
namespace Emby.Server.Implementations.Activity
{
/// <summary>
/// The activity log repository.
/// </summary>
public class ActivityRepository : BaseSqliteRepository, IActivityRepository
{
private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="ActivityRepository"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="appPaths">The server application paths.</param>
/// <param name="fileSystem">The filesystem.</param>
public ActivityRepository(ILogger<ActivityRepository> logger, IServerApplicationPaths appPaths, IFileSystem fileSystem)
: base(logger)
{
@ -28,6 +35,9 @@ namespace Emby.Server.Implementations.Activity
_fileSystem = fileSystem;
}
/// <summary>
/// Initializes the <see cref="ActivityRepository"/>.
/// </summary>
public void Initialize()
{
try
@ -46,16 +56,14 @@ namespace Emby.Server.Implementations.Activity
private void InitializeInternal()
{
using (var connection = GetConnection())
using var connection = GetConnection();
connection.RunQueries(new[]
{
connection.RunQueries(new[]
{
"create table if not exists ActivityLog (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Overview TEXT, ShortOverview TEXT, Type TEXT NOT NULL, ItemId TEXT, UserId TEXT, DateCreated DATETIME NOT NULL, LogSeverity TEXT NOT NULL)",
"drop index if exists idx_ActivityLogEntries"
});
"create table if not exists ActivityLog (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Overview TEXT, ShortOverview TEXT, Type TEXT NOT NULL, ItemId TEXT, UserId TEXT, DateCreated DATETIME NOT NULL, LogSeverity TEXT NOT NULL)",
"drop index if exists idx_ActivityLogEntries"
});
TryMigrate(connection);
}
TryMigrate(connection);
}
private void TryMigrate(ManagedConnection connection)
@ -77,6 +85,7 @@ namespace Emby.Server.Implementations.Activity
}
}
/// <inheritdoc />
public void Create(ActivityLogEntry entry)
{
if (entry == null)
@ -84,39 +93,38 @@ namespace Emby.Server.Implementations.Activity
throw new ArgumentNullException(nameof(entry));
}
using (var connection = GetConnection())
using var connection = GetConnection();
connection.RunInTransaction(db =>
{
connection.RunInTransaction(
db =>
{
using (var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"))
{
statement.TryBind("@Name", entry.Name);
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{
statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}
},
TransactionMode);
}
using var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)");
statement.TryBind("@Name", entry.Name);
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{
statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}, TransactionMode);
}
/// <summary>
/// Adds the provided <see cref="ActivityLogEntry"/> to this repository.
/// </summary>
/// <param name="entry">The activity log entry.</param>
/// <exception cref="ArgumentNullException">If entry is null.</exception>
public void Update(ActivityLogEntry entry)
{
if (entry == null)
@ -124,40 +132,35 @@ namespace Emby.Server.Implementations.Activity
throw new ArgumentNullException(nameof(entry));
}
using (var connection = GetConnection())
using var connection = GetConnection();
connection.RunInTransaction(db =>
{
connection.RunInTransaction(
db =>
{
using (var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id"))
{
statement.TryBind("@Id", entry.Id);
statement.TryBind("@Name", entry.Name);
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{
statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}
},
TransactionMode);
}
using var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id");
statement.TryBind("@Id", entry.Id);
statement.TryBind("@Name", entry.Name);
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{
statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}, TransactionMode);
}
/// <inheritdoc />
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
{
var commandText = BaseActivitySelectText;
@ -170,14 +173,7 @@ namespace Emby.Server.Implementations.Activity
if (hasUserId.HasValue)
{
if (hasUserId.Value)
{
whereClauses.Add("UserId not null");
}
else
{
whereClauses.Add("UserId is null");
}
whereClauses.Add(hasUserId.Value ? "UserId not null" : "UserId is null");
}
var whereTextWithoutPaging = whereClauses.Count == 0 ?
@ -220,38 +216,33 @@ namespace Emby.Server.Implementations.Activity
var list = new List<ActivityLogEntry>();
var result = new QueryResult<ActivityLogEntry>();
using (var connection = GetConnection(true))
{
connection.RunInTransaction(
db =>
{
var statements = PrepareAll(db, statementTexts).ToList();
using var connection = GetConnection(true);
connection.RunInTransaction(
db =>
{
var statements = PrepareAll(db, statementTexts).ToList();
using (var statement = statements[0])
using (var statement = statements[0])
{
if (minDate.HasValue)
{
if (minDate.HasValue)
{
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
}
foreach (var row in statement.ExecuteQuery())
{
list.Add(GetEntry(row));
}
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
}
using (var statement = statements[1])
{
if (minDate.HasValue)
{
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
}
list.AddRange(statement.ExecuteQuery().Select(GetEntry));
}
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
using (var statement = statements[1])
{
if (minDate.HasValue)
{
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
}
},
ReadTransactionMode);
}
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
}
},
ReadTransactionMode);
result.Items = list;
return result;

@ -15,6 +15,11 @@ namespace Emby.Server.Implementations.AppBase
/// <summary>
/// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
/// </summary>
/// <param name="programDataPath">The program data path.</param>
/// <param name="logDirectoryPath">The log directory path.</param>
/// <param name="configurationDirectoryPath">The configuration directory path.</param>
/// <param name="cacheDirectoryPath">The cache directory path.</param>
/// <param name="webDirectoryPath">The web directory path.</param>
protected BaseApplicationPaths(
string programDataPath,
string logDirectoryPath,

@ -36,24 +36,22 @@ namespace Emby.Server.Implementations.AppBase
configuration = Activator.CreateInstance(type);
}
using (var stream = new MemoryStream())
{
xmlSerializer.SerializeToStream(configuration, stream);
// Take the object we just got and serialize it back to bytes
var newBytes = stream.ToArray();
using var stream = new MemoryStream();
xmlSerializer.SerializeToStream(configuration, stream);
// If the file didn't exist before, or if something has changed, re-save
if (buffer == null || !buffer.SequenceEqual(newBytes))
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
// Take the object we just got and serialize it back to bytes
var newBytes = stream.ToArray();
// Save it after load in case we got new items
File.WriteAllBytes(path, newBytes);
}
// If the file didn't exist before, or if something has changed, re-save
if (buffer == null || !buffer.SequenceEqual(newBytes))
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
return configuration;
// Save it after load in case we got new items
File.WriteAllBytes(path, newBytes);
}
return configuration;
}
}
}

@ -106,6 +106,7 @@ using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
using Prometheus.DotNetRuntime;
namespace Emby.Server.Implementations
{
@ -259,6 +260,12 @@ namespace Emby.Server.Implementations
_startupOptions = options;
// Initialize runtime stat collection
if (ServerConfigurationManager.Configuration.EnableMetrics)
{
DotNetRuntimeStatsBuilder.Default().StartCollecting();
}
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
_networkManager.NetworkChanged += OnNetworkChanged;
@ -1185,7 +1192,7 @@ namespace Emby.Server.Implementations
public bool SupportsHttps => Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy;
public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken)
public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken, bool forceHttp = false)
{
try
{
@ -1194,7 +1201,7 @@ namespace Emby.Server.Implementations
foreach (var address in addresses)
{
return GetLocalApiUrl(address);
return GetLocalApiUrl(address, forceHttp);
}
return null;
@ -1224,7 +1231,7 @@ namespace Emby.Server.Implementations
}
/// <inheritdoc />
public string GetLocalApiUrl(IPAddress ipAddress)
public string GetLocalApiUrl(IPAddress ipAddress, bool forceHttp = false)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
@ -1234,20 +1241,21 @@ namespace Emby.Server.Implementations
str.CopyTo(span.Slice(1));
span[^1] = ']';
return GetLocalApiUrl(span);
return GetLocalApiUrl(span, forceHttp);
}
return GetLocalApiUrl(ipAddress.ToString());
return GetLocalApiUrl(ipAddress.ToString(), forceHttp);
}
/// <inheritdoc />
public string GetLocalApiUrl(ReadOnlySpan<char> host)
public string GetLocalApiUrl(ReadOnlySpan<char> host, bool forceHttp = false)
{
var url = new StringBuilder(64);
url.Append(EnableHttps ? "https://" : "http://")
bool useHttps = EnableHttps && !forceHttp;
url.Append(useHttps ? "https://" : "http://")
.Append(host)
.Append(':')
.Append(EnableHttps ? HttpsPort : HttpPort);
.Append(useHttps ? HttpsPort : HttpPort);
string baseUrl = ServerConfigurationManager.Configuration.BaseUrl;
if (baseUrl.Length != 0)

@ -22,10 +22,8 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
using (var fileStream = File.OpenRead(sourceFile))
{
ExtractAll(fileStream, targetPath, overwriteExistingFiles);
}
using var fileStream = File.OpenRead(sourceFile);
ExtractAll(fileStream, targetPath, overwriteExistingFiles);
}
/// <summary>
@ -36,70 +34,61 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles)
{
using (var reader = ReaderFactory.Open(source))
using var reader = ReaderFactory.Open(source);
var options = new ExtractionOptions
{
var options = new ExtractionOptions();
options.ExtractFullPath = true;
if (overwriteExistingFiles)
{
options.Overwrite = true;
}
ExtractFullPath = true
};
reader.WriteAllToDirectory(targetPath, options);
if (overwriteExistingFiles)
{
options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
}
/// <inheritdoc />
public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles)
{
using (var reader = ZipReader.Open(source))
using var reader = ZipReader.Open(source);
var options = new ExtractionOptions
{
var options = new ExtractionOptions();
options.ExtractFullPath = true;
ExtractFullPath = true,
Overwrite = overwriteExistingFiles
};
if (overwriteExistingFiles)
{
options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
}
reader.WriteAllToDirectory(targetPath, options);
}
/// <inheritdoc />
public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles)
{
using (var reader = GZipReader.Open(source))
using var reader = GZipReader.Open(source);
var options = new ExtractionOptions
{
var options = new ExtractionOptions();
options.ExtractFullPath = true;
ExtractFullPath = true,
Overwrite = overwriteExistingFiles
};
if (overwriteExistingFiles)
{
options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
}
reader.WriteAllToDirectory(targetPath, options);
}
/// <inheritdoc />
public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName)
{
using (var reader = GZipReader.Open(source))
using var reader = GZipReader.Open(source);
if (reader.MoveToNextEntry())
{
if (reader.MoveToNextEntry())
var entry = reader.Entry;
var filename = entry.Key;
if (string.IsNullOrWhiteSpace(filename))
{
var entry = reader.Entry;
var filename = entry.Key;
if (string.IsNullOrWhiteSpace(filename))
{
filename = defaultFileName;
}
reader.WriteEntryToFile(Path.Combine(targetPath, filename));
filename = defaultFileName;
}
reader.WriteEntryToFile(Path.Combine(targetPath, filename));
}
}
@ -111,10 +100,8 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
using (var fileStream = File.OpenRead(sourceFile))
{
ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles);
}
using var fileStream = File.OpenRead(sourceFile);
ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles);
}
/// <summary>
@ -125,21 +112,15 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFrom7z(Stream source, string targetPath, bool overwriteExistingFiles)
{
using (var archive = SevenZipArchive.Open(source))
using var archive = SevenZipArchive.Open(source);
using var reader = archive.ExtractAllEntries();
var options = new ExtractionOptions
{
using (var reader = archive.ExtractAllEntries())
{
var options = new ExtractionOptions();
options.ExtractFullPath = true;
if (overwriteExistingFiles)
{
options.Overwrite = true;
}
ExtractFullPath = true,
Overwrite = overwriteExistingFiles
};
reader.WriteAllToDirectory(targetPath, options);
}
}
reader.WriteAllToDirectory(targetPath, options);
}
/// <summary>
@ -150,10 +131,8 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFromTar(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
using (var fileStream = File.OpenRead(sourceFile))
{
ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles);
}
using var fileStream = File.OpenRead(sourceFile);
ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles);
}
/// <summary>
@ -164,21 +143,15 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFromTar(Stream source, string targetPath, bool overwriteExistingFiles)
{
using (var archive = TarArchive.Open(source))
using var archive = TarArchive.Open(source);
using var reader = archive.ExtractAllEntries();
var options = new ExtractionOptions
{
using (var reader = archive.ExtractAllEntries())
{
var options = new ExtractionOptions();
options.ExtractFullPath = true;
ExtractFullPath = true,
Overwrite = overwriteExistingFiles
};
if (overwriteExistingFiles)
{
options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
}
}
reader.WriteAllToDirectory(targetPath, options);
}
}
}

@ -1,13 +1,15 @@
#pragma warning disable CS1591
using System.Collections.Generic;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.Branding;
namespace Emby.Server.Implementations.Branding
{
/// <summary>
/// A configuration factory for <see cref="BrandingOptions"/>.
/// </summary>
public class BrandingConfigurationFactory : IConfigurationFactory
{
/// <inheritdoc />
public IEnumerable<ConfigurationStore> GetConfigurations()
{
return new[]

@ -1,7 +1,6 @@
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Channels;
@ -11,6 +10,9 @@ using MediaBrowser.Model.Dto;
namespace Emby.Server.Implementations.Channels
{
/// <summary>
/// A media source provider for channels.
/// </summary>
public class ChannelDynamicMediaSourceProvider : IMediaSourceProvider
{
private readonly ChannelManager _channelManager;
@ -27,12 +29,9 @@ namespace Emby.Server.Implementations.Channels
/// <inheritdoc />
public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken)
{
if (item.SourceType == SourceType.Channel)
{
return _channelManager.GetDynamicMediaSources(item, cancellationToken);
}
return Task.FromResult<IEnumerable<MediaSourceInfo>>(new List<MediaSourceInfo>());
return item.SourceType == SourceType.Channel
? _channelManager.GetDynamicMediaSources(item, cancellationToken)
: Task.FromResult(Enumerable.Empty<MediaSourceInfo>());
}
/// <inheritdoc />

@ -1,5 +1,3 @@
#pragma warning disable CS1591
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@ -11,22 +9,32 @@ using MediaBrowser.Model.Entities;
namespace Emby.Server.Implementations.Channels
{
/// <summary>
/// An image provider for channels.
/// </summary>
public class ChannelImageProvider : IDynamicImageProvider, IHasItemChangeMonitor
{
private readonly IChannelManager _channelManager;
/// <summary>
/// Initializes a new instance of the <see cref="ChannelImageProvider"/> class.
/// </summary>
/// <param name="channelManager">The channel manager.</param>
public ChannelImageProvider(IChannelManager channelManager)
{
_channelManager = channelManager;
}
/// <inheritdoc />
public string Name => "Channel Image Provider";
/// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return GetChannel(item).GetSupportedChannelImages();
}
/// <inheritdoc />
public Task<DynamicImageResponse> GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken)
{
var channel = GetChannel(item);
@ -34,6 +42,7 @@ namespace Emby.Server.Implementations.Channels
return channel.GetChannelImage(type, cancellationToken);
}
/// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is Channel;
@ -46,6 +55,7 @@ namespace Emby.Server.Implementations.Channels
return ((ChannelManager)_channelManager).GetChannelProvider(channel);
}
/// <inheritdoc />
public bool HasChanged(BaseItem item, IDirectoryService directoryService)
{
return GetSupportedImages(item).Any(i => !item.HasImage(i));

@ -1,5 +1,3 @@
#pragma warning disable CS1591
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@ -29,6 +27,9 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Channels
{
/// <summary>
/// The LiveTV channel manager.
/// </summary>
public class ChannelManager : IChannelManager
{
private readonly IUserManager _userManager;
@ -45,7 +46,19 @@ namespace Emby.Server.Implementations.Channels
new ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>>();
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
/// <summary>
/// Initializes a new instance of the <see cref="ChannelManager"/> class.
/// </summary>
/// <param name="userManager">The user manager.</param>
/// <param name="dtoService">The dto service.</param>
/// <param name="libraryManager">The library manager.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="config">The server configuration manager.</param>
/// <param name="fileSystem">The filesystem.</param>
/// <param name="userDataManager">The user data manager.</param>
/// <param name="jsonSerializer">The JSON serializer.</param>
/// <param name="providerManager">The provider manager.</param>
public ChannelManager(
IUserManager userManager,
IDtoService dtoService,
@ -72,11 +85,13 @@ namespace Emby.Server.Implementations.Channels
private static TimeSpan CacheLength => TimeSpan.FromHours(3);
/// <inheritdoc />
public void AddParts(IEnumerable<IChannel> channels)
{
Channels = channels.ToArray();
}
/// <inheritdoc />
public bool EnableMediaSourceDisplay(BaseItem item)
{
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
@ -85,6 +100,7 @@ namespace Emby.Server.Implementations.Channels
return !(channel is IDisableMediaSourceDisplay);
}
/// <inheritdoc />
public bool CanDelete(BaseItem item)
{
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
@ -93,6 +109,7 @@ namespace Emby.Server.Implementations.Channels
return channel is ISupportsDelete supportsDelete && supportsDelete.CanDelete(item);
}
/// <inheritdoc />
public bool EnableMediaProbe(BaseItem item)
{
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
@ -101,6 +118,7 @@ namespace Emby.Server.Implementations.Channels
return channel is ISupportsMediaProbe;
}
/// <inheritdoc />
public Task DeleteItem(BaseItem item)
{
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
@ -127,11 +145,16 @@ namespace Emby.Server.Implementations.Channels
.OrderBy(i => i.Name);
}
/// <summary>
/// Get the installed channel IDs.
/// </summary>
/// <returns>An <see cref="IEnumerable{T}"/> containing installed channel IDs.</returns>
public IEnumerable<Guid> GetInstalledChannelIds()
{
return GetAllChannels().Select(i => GetInternalChannelId(i.Name));
}
/// <inheritdoc />
public QueryResult<Channel> GetChannelsInternal(ChannelQuery query)
{
var user = query.UserId.Equals(Guid.Empty)
@ -249,6 +272,7 @@ namespace Emby.Server.Implementations.Channels
};
}
/// <inheritdoc />
public QueryResult<BaseItemDto> GetChannels(ChannelQuery query)
{
var user = query.UserId.Equals(Guid.Empty)
@ -271,6 +295,12 @@ namespace Emby.Server.Implementations.Channels
return result;
}
/// <summary>
/// Refreshes the associated channels.
/// </summary>
/// <param name="progress">The progress.</param>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
/// <returns>The completed task.</returns>
public async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
{
var allChannelsList = GetAllChannels().ToList();
@ -304,14 +334,7 @@ namespace Emby.Server.Implementations.Channels
private Channel GetChannelEntity(IChannel channel)
{
var item = GetChannel(GetInternalChannelId(channel.Name));
if (item == null)
{
item = GetChannel(channel, CancellationToken.None).Result;
}
return item;
return GetChannel(GetInternalChannelId(channel.Name)) ?? GetChannel(channel, CancellationToken.None).Result;
}
private List<MediaSourceInfo> GetSavedMediaSources(BaseItem item)
@ -350,6 +373,7 @@ namespace Emby.Server.Implementations.Channels
_jsonSerializer.SerializeToFile(mediaSources, path);
}
/// <inheritdoc />
public IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken)
{
IEnumerable<MediaSourceInfo> results = GetSavedMediaSources(item);
@ -359,6 +383,12 @@ namespace Emby.Server.Implementations.Channels
.ToList();
}
/// <summary>
/// Gets the dynamic media sources based on the provided item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
/// <returns>The task representing the operation to get the media sources.</returns>
public async Task<IEnumerable<MediaSourceInfo>> GetDynamicMediaSources(BaseItem item, CancellationToken cancellationToken)
{
var channel = GetChannel(item.ChannelId);
@ -403,7 +433,7 @@ namespace Emby.Server.Implementations.Channels
private static MediaSourceInfo NormalizeMediaSource(BaseItem item, MediaSourceInfo info)
{
info.RunTimeTicks = info.RunTimeTicks ?? item.RunTimeTicks;
info.RunTimeTicks ??= item.RunTimeTicks;
return info;
}
@ -481,31 +511,33 @@ namespace Emby.Server.Implementations.Channels
private static string GetOfficialRating(ChannelParentalRating rating)
{
switch (rating)
{
case ChannelParentalRating.Adult:
return "XXX";
case ChannelParentalRating.UsR:
return "R";
case ChannelParentalRating.UsPG13:
return "PG-13";
case ChannelParentalRating.UsPG:
return "PG";
default:
return null;
}
return rating switch
{
ChannelParentalRating.Adult => "XXX",
ChannelParentalRating.UsR => "R",
ChannelParentalRating.UsPG13 => "PG-13",
ChannelParentalRating.UsPG => "PG",
_ => null
};
}
/// <summary>
/// Gets a channel with the provided Guid.
/// </summary>
/// <param name="id">The Guid.</param>
/// <returns>The corresponding channel.</returns>
public Channel GetChannel(Guid id)
{
return _libraryManager.GetItemById(id) as Channel;
}
/// <inheritdoc />
public Channel GetChannel(string id)
{
return _libraryManager.GetItemById(id) as Channel;
}
/// <inheritdoc />
public ChannelFeatures[] GetAllChannelFeatures()
{
return _libraryManager.GetItemIds(
@ -516,6 +548,7 @@ namespace Emby.Server.Implementations.Channels
}).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
}
/// <inheritdoc />
public ChannelFeatures GetChannelFeatures(string id)
{
if (string.IsNullOrEmpty(id))
@ -529,6 +562,11 @@ namespace Emby.Server.Implementations.Channels
return GetChannelFeaturesDto(channel, channelProvider, channelProvider.GetChannelFeatures());
}
/// <summary>
/// Checks whether the provided Guid supports external transfer.
/// </summary>
/// <param name="channelId">The Guid.</param>
/// <returns>Whether or not the provided Guid supports external transfer.</returns>
public bool SupportsExternalTransfer(Guid channelId)
{
var channelProvider = GetChannelProvider(channelId);
@ -536,6 +574,13 @@ namespace Emby.Server.Implementations.Channels
return channelProvider.GetChannelFeatures().SupportsContentDownloading;
}
/// <summary>
/// Gets the provided channel's supported features.
/// </summary>
/// <param name="channel">The channel.</param>
/// <param name="provider">The provider.</param>
/// <param name="features">The features.</param>
/// <returns>The supported features.</returns>
public ChannelFeatures GetChannelFeaturesDto(
Channel channel,
IChannel provider,
@ -570,6 +615,7 @@ namespace Emby.Server.Implementations.Channels
return _libraryManager.GetNewItemId("Channel " + name, typeof(Channel));
}
/// <inheritdoc />
public async Task<QueryResult<BaseItemDto>> GetLatestChannelItems(InternalItemsQuery query, CancellationToken cancellationToken)
{
var internalResult = await GetLatestChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
@ -588,6 +634,7 @@ namespace Emby.Server.Implementations.Channels
return result;
}
/// <inheritdoc />
public async Task<QueryResult<BaseItem>> GetLatestChannelItemsInternal(InternalItemsQuery query, CancellationToken cancellationToken)
{
var channels = GetAllChannels().Where(i => i is ISupportsLatestMedia).ToArray();
@ -666,6 +713,7 @@ namespace Emby.Server.Implementations.Channels
}
}
/// <inheritdoc />
public async Task<QueryResult<BaseItem>> GetChannelItemsInternal(InternalItemsQuery query, IProgress<double> progress, CancellationToken cancellationToken)
{
// Get the internal channel entity
@ -727,6 +775,7 @@ namespace Emby.Server.Implementations.Channels
return _libraryManager.GetItemsResult(query);
}
/// <inheritdoc />
public async Task<QueryResult<BaseItemDto>> GetChannelItems(InternalItemsQuery query, CancellationToken cancellationToken)
{
var internalResult = await GetChannelItemsInternal(query, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
@ -796,7 +845,7 @@ namespace Emby.Server.Implementations.Channels
var query = new InternalChannelItemQuery
{
UserId = user == null ? Guid.Empty : user.Id,
UserId = user?.Id ?? Guid.Empty,
SortBy = sortField,
SortDescending = sortDescending,
FolderId = externalFolderId
@ -923,60 +972,32 @@ namespace Emby.Server.Implementations.Channels
if (info.Type == ChannelItemType.Folder)
{
if (info.FolderType == ChannelFolderType.MusicAlbum)
{
item = GetItemById<MusicAlbum>(info.Id, channelProvider.Name, out isNew);
}
else if (info.FolderType == ChannelFolderType.MusicArtist)
{
item = GetItemById<MusicArtist>(info.Id, channelProvider.Name, out isNew);
}
else if (info.FolderType == ChannelFolderType.PhotoAlbum)
{
item = GetItemById<PhotoAlbum>(info.Id, channelProvider.Name, out isNew);
}
else if (info.FolderType == ChannelFolderType.Series)
{
item = GetItemById<Series>(info.Id, channelProvider.Name, out isNew);
}
else if (info.FolderType == ChannelFolderType.Season)
item = info.FolderType switch
{
item = GetItemById<Season>(info.Id, channelProvider.Name, out isNew);
}
else
{
item = GetItemById<Folder>(info.Id, channelProvider.Name, out isNew);
}
ChannelFolderType.MusicAlbum => GetItemById<MusicAlbum>(info.Id, channelProvider.Name, out isNew),
ChannelFolderType.MusicArtist => GetItemById<MusicArtist>(info.Id, channelProvider.Name, out isNew),
ChannelFolderType.PhotoAlbum => GetItemById<PhotoAlbum>(info.Id, channelProvider.Name, out isNew),
ChannelFolderType.Series => GetItemById<Series>(info.Id, channelProvider.Name, out isNew),
ChannelFolderType.Season => GetItemById<Season>(info.Id, channelProvider.Name, out isNew),
_ => GetItemById<Folder>(info.Id, channelProvider.Name, out isNew)
};
}
else if (info.MediaType == ChannelMediaType.Audio)
{
if (info.ContentType == ChannelMediaContentType.Podcast)
{
item = GetItemById<AudioBook>(info.Id, channelProvider.Name, out isNew);
}
else
{
item = GetItemById<Audio>(info.Id, channelProvider.Name, out isNew);
}
item = info.ContentType == ChannelMediaContentType.Podcast
? GetItemById<AudioBook>(info.Id, channelProvider.Name, out isNew)
: GetItemById<Audio>(info.Id, channelProvider.Name, out isNew);
}
else
{
if (info.ContentType == ChannelMediaContentType.Episode)
item = info.ContentType switch
{
item = GetItemById<Episode>(info.Id, channelProvider.Name, out isNew);
}
else if (info.ContentType == ChannelMediaContentType.Movie)
{
item = GetItemById<Movie>(info.Id, channelProvider.Name, out isNew);
}
else if (info.ContentType == ChannelMediaContentType.Trailer || info.ExtraType == ExtraType.Trailer)
{
item = GetItemById<Trailer>(info.Id, channelProvider.Name, out isNew);
}
else
{
item = GetItemById<Video>(info.Id, channelProvider.Name, out isNew);
}
ChannelMediaContentType.Episode => GetItemById<Episode>(info.Id, channelProvider.Name, out isNew),
ChannelMediaContentType.Movie => GetItemById<Movie>(info.Id, channelProvider.Name, out isNew),
var x when x == ChannelMediaContentType.Trailer || info.ExtraType == ExtraType.Trailer
=> GetItemById<Trailer>(info.Id, channelProvider.Name, out isNew),
_ => GetItemById<Video>(info.Id, channelProvider.Name, out isNew)
};
}
var enableMediaProbe = channelProvider is ISupportsMediaProbe;

@ -1,5 +1,3 @@
#pragma warning disable CS1591
using System;
using System.Linq;
using System.Threading;
@ -11,12 +9,21 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Channels
{
/// <summary>
/// A task to remove all non-installed channels from the database.
/// </summary>
public class ChannelPostScanTask
{
private readonly IChannelManager _channelManager;
private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager;
/// <summary>
/// Initializes a new instance of the <see cref="ChannelPostScanTask"/> class.
/// </summary>
/// <param name="channelManager">The channel manager.</param>
/// <param name="logger">The logger.</param>
/// <param name="libraryManager">The library manager.</param>
public ChannelPostScanTask(IChannelManager channelManager, ILogger logger, ILibraryManager libraryManager)
{
_channelManager = channelManager;
@ -24,6 +31,12 @@ namespace Emby.Server.Implementations.Channels
_libraryManager = libraryManager;
}
/// <summary>
/// Runs this task.
/// </summary>
/// <param name="progress">The progress.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The completed task.</returns>
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
CleanDatabase(cancellationToken);

@ -1,5 +1,3 @@
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Threading;
@ -13,6 +11,9 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Channels
{
/// <summary>
/// The "Refresh Channels" scheduled task.
/// </summary>
public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask
{
private readonly IChannelManager _channelManager;
@ -20,6 +21,13 @@ namespace Emby.Server.Implementations.Channels
private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _localization;
/// <summary>
/// Initializes a new instance of the <see cref="RefreshChannelsScheduledTask"/> class.
/// </summary>
/// <param name="channelManager">The channel manager.</param>
/// <param name="logger">The logger.</param>
/// <param name="libraryManager">The library manager.</param>
/// <param name="localization">The localization manager.</param>
public RefreshChannelsScheduledTask(
IChannelManager channelManager,
ILogger<RefreshChannelsScheduledTask> logger,

@ -1,5 +1,3 @@
#pragma warning disable CS1591
using System.Collections.Generic;
using System.Linq;
using Emby.Server.Implementations.Images;
@ -15,8 +13,18 @@ using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.Collections
{
/// <summary>
/// A collection image provider.
/// </summary>
public class CollectionImageProvider : BaseDynamicImageProvider<BoxSet>
{
/// <summary>
/// Initializes a new instance of the <see cref="CollectionImageProvider"/> class.
/// </summary>
/// <param name="fileSystem">The filesystem.</param>
/// <param name="providerManager">The provider manager.</param>
/// <param name="applicationPaths">The application paths.</param>
/// <param name="imageProcessor">The image processor.</param>
public CollectionImageProvider(
IFileSystem fileSystem,
IProviderManager providerManager,
@ -26,6 +34,7 @@ namespace Emby.Server.Implementations.Collections
{
}
/// <inheritdoc />
protected override bool Supports(BaseItem item)
{
// Right now this is the only way to prevent this image from getting created ahead of internet image providers
@ -37,6 +46,7 @@ namespace Emby.Server.Implementations.Collections
return base.Supports(item);
}
/// <inheritdoc />
protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item)
{
var playlist = (BoxSet)item;
@ -46,13 +56,12 @@ namespace Emby.Server.Implementations.Collections
{
var subItem = i;
if (subItem is Episode episode)
var episode = subItem as Episode;
var series = episode?.Series;
if (series != null && series.HasImage(ImageType.Primary))
{
var series = episode.Series;
if (series != null && series.HasImage(ImageType.Primary))
{
return series;
}
return series;
}
if (subItem.HasImage(ImageType.Primary))
@ -78,6 +87,7 @@ namespace Emby.Server.Implementations.Collections
.ToList();
}
/// <inheritdoc />
protected override string CreateImage(BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex)
{
return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary);

@ -1,5 +1,3 @@
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Globalization;
@ -23,6 +21,9 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Collections
{
/// <summary>
/// The collection manager.
/// </summary>
public class CollectionManager : ICollectionManager
{
private readonly ILibraryManager _libraryManager;
@ -33,6 +34,16 @@ namespace Emby.Server.Implementations.Collections
private readonly ILocalizationManager _localizationManager;
private readonly IApplicationPaths _appPaths;
/// <summary>
/// Initializes a new instance of the <see cref="CollectionManager"/> class.
/// </summary>
/// <param name="libraryManager">The library manager.</param>
/// <param name="appPaths">The application paths.</param>
/// <param name="localizationManager">The localization manager.</param>
/// <param name="fileSystem">The filesystem.</param>
/// <param name="iLibraryMonitor">The library monitor.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="providerManager">The provider manager.</param>
public CollectionManager(
ILibraryManager libraryManager,
IApplicationPaths appPaths,
@ -51,10 +62,13 @@ namespace Emby.Server.Implementations.Collections
_appPaths = appPaths;
}
/// <inheritdoc />
public event EventHandler<CollectionCreatedEventArgs> CollectionCreated;
/// <inheritdoc />
public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection;
/// <inheritdoc />
public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection;
private IEnumerable<Folder> FindFolders(string path)
@ -116,6 +130,7 @@ namespace Emby.Server.Implementations.Collections
: folder.GetChildren(user, true).OfType<BoxSet>();
}
/// <inheritdoc />
public BoxSet CreateCollection(CollectionCreationOptions options)
{
var name = options.Name;
@ -180,11 +195,13 @@ namespace Emby.Server.Implementations.Collections
}
}
/// <inheritdoc />
public void AddToCollection(Guid collectionId, IEnumerable<string> ids)
{
AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
}
/// <inheritdoc />
public void AddToCollection(Guid collectionId, IEnumerable<Guid> ids)
{
AddToCollection(collectionId, ids.Select(i => i.ToString("N", CultureInfo.InvariantCulture)), true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
@ -247,11 +264,13 @@ namespace Emby.Server.Implementations.Collections
}
}
/// <inheritdoc />
public void RemoveFromCollection(Guid collectionId, IEnumerable<string> itemIds)
{
RemoveFromCollection(collectionId, itemIds.Select(i => new Guid(i)));
}
/// <inheritdoc />
public void RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds)
{
var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
@ -305,6 +324,7 @@ namespace Emby.Server.Implementations.Collections
});
}
/// <inheritdoc />
public IEnumerable<BaseItem> CollapseItemsWithinBoxSets(IEnumerable<BaseItem> items, User user)
{
var results = new Dictionary<Guid, BaseItem>();
@ -313,9 +333,7 @@ namespace Emby.Server.Implementations.Collections
foreach (var item in items)
{
var grouping = item as ISupportsBoxSetGrouping;
if (grouping == null)
if (!(item is ISupportsBoxSetGrouping))
{
results[item.Id] = item;
}
@ -345,12 +363,21 @@ namespace Emby.Server.Implementations.Collections
}
}
/// <summary>
/// The collection manager entry point.
/// </summary>
public sealed class CollectionManagerEntryPoint : IServerEntryPoint
{
private readonly CollectionManager _collectionManager;
private readonly IServerConfigurationManager _config;
private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="CollectionManagerEntryPoint"/> class.
/// </summary>
/// <param name="collectionManager">The collection manager.</param>
/// <param name="config">The server configuration manager.</param>
/// <param name="logger">The logger.</param>
public CollectionManagerEntryPoint(
ICollectionManager collectionManager,
IServerConfigurationManager config,

@ -67,23 +67,22 @@ namespace Emby.Server.Implementations.Configuration
/// <summary>
/// Updates the metadata path.
/// </summary>
/// <exception cref="UnauthorizedAccessException">If the directory does not exist, and the caller does not have the required permission to create it.</exception>
/// <exception cref="NotSupportedException">If there is a custom path transcoding path specified, but it is invalid.</exception>
/// <exception cref="IOException">If the directory does not exist, and it also could not be created.</exception>
private void UpdateMetadataPath()
{
if (string.IsNullOrWhiteSpace(Configuration.MetadataPath))
{
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Path.Combine(ApplicationPaths.ProgramDataPath, "metadata");
}
else
{
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Configuration.MetadataPath;
}
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrWhiteSpace(Configuration.MetadataPath)
? ApplicationPaths.DefaultInternalMetadataPath
: Configuration.MetadataPath;
Directory.CreateDirectory(ApplicationPaths.InternalMetadataPath);
}
/// <summary>
/// Replaces the configuration.
/// </summary>
/// <param name="newConfiguration">The new configuration.</param>
/// <exception cref="DirectoryNotFoundException"></exception>
/// <exception cref="DirectoryNotFoundException">If the configuration path doesn't exist.</exception>
public override void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
{
var newConfig = (ServerConfiguration)newConfiguration;

@ -31,7 +31,7 @@ namespace Emby.Server.Implementations.Cryptography
private RandomNumberGenerator _randomNumberGenerator;
private bool _disposed = false;
private bool _disposed;
/// <summary>
/// Initializes a new instance of the <see cref="CryptographyProvider"/> class.
@ -56,15 +56,13 @@ namespace Emby.Server.Implementations.Cryptography
{
// downgrading for now as we need this library to be dotnetstandard compliant
// with this downgrade we'll add a check to make sure we're on the downgrade method at the moment
if (method == DefaultHashMethod)
if (method != DefaultHashMethod)
{
using (var r = new Rfc2898DeriveBytes(bytes, salt, iterations))
{
return r.GetBytes(32);
}
throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
}
throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
using var r = new Rfc2898DeriveBytes(bytes, salt, iterations);
return r.GetBytes(32);
}
/// <inheritdoc />
@ -74,25 +72,22 @@ namespace Emby.Server.Implementations.Cryptography
{
return PBKDF2(hashMethod, bytes, salt, DefaultIterations);
}
else if (_supportedHashMethods.Contains(hashMethod))
if (!_supportedHashMethods.Contains(hashMethod))
{
throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
}
using var h = HashAlgorithm.Create(hashMethod);
if (salt.Length == 0)
{
using (var h = HashAlgorithm.Create(hashMethod))
{
if (salt.Length == 0)
{
return h.ComputeHash(bytes);
}
else
{
byte[] salted = new byte[bytes.Length + salt.Length];
Array.Copy(bytes, salted, bytes.Length);
Array.Copy(salt, 0, salted, bytes.Length, salt.Length);
return h.ComputeHash(salted);
}
}
return h.ComputeHash(bytes);
}
throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
byte[] salted = new byte[bytes.Length + salt.Length];
Array.Copy(bytes, salted, bytes.Length);
Array.Copy(salt, 0, salted, bytes.Length, salt.Length);
return h.ComputeHash(salted);
}
/// <inheritdoc />

@ -375,5 +375,15 @@ namespace Emby.Server.Implementations.Data
return userData;
}
/// <inheritdoc/>
/// <remarks>
/// There is nothing to dispose here since <see cref="BaseSqliteRepository.WriteLock"/> and
/// <see cref="BaseSqliteRepository.WriteConnection"/> are managed by <see cref="SqliteItemRepository"/>.
/// See <see cref="Initialize(IUserManager, SemaphoreSlim, SQLiteDatabaseConnection)"/>.
/// </remarks>
protected override void Dispose(bool dispose)
{
}
}
}

@ -39,6 +39,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.3" />
<PackageReference Include="Mono.Nat" Version="2.0.1" />
<PackageReference Include="prometheus-net.DotNetRuntime" Version="3.3.1" />
<PackageReference Include="ServiceStack.Text.Core" Version="5.8.0" />
<PackageReference Include="sharpcompress" Version="0.25.0" />
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" />

@ -426,7 +426,7 @@ namespace Emby.Server.Implementations.HttpServer
if (!noCache)
{
if (!DateTime.TryParseExact(requestContext.Headers[HeaderNames.IfModifiedSince], HttpDateFormat, _enUSculture, DateTimeStyles.AssumeUniversal, out var ifModifiedSinceHeader))
if (!DateTime.TryParseExact(requestContext.Headers[HeaderNames.IfModifiedSince], HttpDateFormat, _enUSculture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out var ifModifiedSinceHeader))
{
_logger.LogDebug("Failed to parse If-Modified-Since header date: {0}", requestContext.Headers[HeaderNames.IfModifiedSince]);
return null;

@ -82,6 +82,10 @@ namespace Emby.Server.Implementations.HttpServer
{
return null;
}
else if (inString.Length == 0)
{
return inString;
}
var newString = new StringBuilder(inString.Length);

@ -35,7 +35,8 @@ namespace Emby.Server.Implementations.Library
return null;
}
public static int? GetDefaultSubtitleStreamIndex(List<MediaStream> streams,
public static int? GetDefaultSubtitleStreamIndex(
List<MediaStream> streams,
string[] preferredLanguages,
SubtitlePlaybackMode mode,
string audioTrackLanguage)
@ -115,7 +116,8 @@ namespace Emby.Server.Implementations.Library
.ThenBy(i => i.Index);
}
public static void SetSubtitleStreamScores(List<MediaStream> streams,
public static void SetSubtitleStreamScores(
List<MediaStream> streams,
string[] preferredLanguages,
SubtitlePlaybackMode mode,
string audioTrackLanguage)

@ -1,3 +1,5 @@
#nullable enable
using System;
using System.Text.RegularExpressions;
@ -12,24 +14,24 @@ namespace Emby.Server.Implementations.Library
/// Gets the attribute value.
/// </summary>
/// <param name="str">The STR.</param>
/// <param name="attrib">The attrib.</param>
/// <param name="attribute">The attrib.</param>
/// <returns>System.String.</returns>
/// <exception cref="ArgumentNullException">attrib</exception>
public static string GetAttributeValue(this string str, string attrib)
/// <exception cref="ArgumentException"><paramref name="str" /> or <paramref name="attribute" /> is empty.</exception>
public static string? GetAttributeValue(this string str, string attribute)
{
if (string.IsNullOrEmpty(str))
if (str.Length == 0)
{
throw new ArgumentNullException(nameof(str));
throw new ArgumentException("String can't be empty.", nameof(str));
}
if (string.IsNullOrEmpty(attrib))
if (attribute.Length == 0)
{
throw new ArgumentNullException(nameof(attrib));
throw new ArgumentException("String can't be empty.", nameof(attribute));
}
string srch = "[" + attrib + "=";
string srch = "[" + attribute + "=";
int start = str.IndexOf(srch, StringComparison.OrdinalIgnoreCase);
if (start > -1)
if (start != -1)
{
start += srch.Length;
int end = str.IndexOf(']', start);
@ -37,7 +39,7 @@ namespace Emby.Server.Implementations.Library
}
// for imdbid we also accept pattern matching
if (string.Equals(attrib, "imdbid", StringComparison.OrdinalIgnoreCase))
if (string.Equals(attribute, "imdbid", StringComparison.OrdinalIgnoreCase))
{
var m = Regex.Match(str, "tt([0-9]{7,8})", RegexOptions.IgnoreCase);
return m.Success ? m.Value : null;

@ -118,10 +118,12 @@ namespace Emby.Server.Implementations.Library
{
throw new ArgumentNullException(nameof(fileSystem));
}
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
if (args == null)
{
throw new ArgumentNullException(nameof(args));

@ -1059,7 +1059,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
var stream = new MediaSourceInfo
{
EncoderPath = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
EncoderPath = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
EncoderProtocol = MediaProtocol.Http,
Path = info.Path,
Protocol = MediaProtocol.File,

@ -121,7 +121,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
//OpenedMediaSource.Path = tempFile;
//OpenedMediaSource.ReadAtNativeFramerate = true;
MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Protocol = MediaProtocol.Http;
//OpenedMediaSource.SupportsDirectPlay = false;
//OpenedMediaSource.SupportsDirectStream = true;

@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
//OpenedMediaSource.Path = tempFile;
//OpenedMediaSource.ReadAtNativeFramerate = true;
MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Protocol = MediaProtocol.Http;
//OpenedMediaSource.Path = TempFilePath;

@ -1,5 +1,5 @@
{
"Albums": "Άλμπουμ",
"Albums": "Άλμπουμς",
"AppDeviceValues": "Εφαρμογή: {0}, Συσκευή: {1}",
"Application": "Εφαρμογή",
"Artists": "Καλλιτέχνες",
@ -92,5 +92,27 @@
"UserStoppedPlayingItemWithValues": "{0} τελείωσε να παίζει {1} σε {2}",
"ValueHasBeenAddedToLibrary": "{0} προστέθηκαν στη βιβλιοθήκη πολυμέσων σας",
"ValueSpecialEpisodeName": "Σπέσιαλ - {0}",
"VersionNumber": "Έκδοση {0}"
"VersionNumber": "Έκδοση {0}",
"TaskRefreshPeople": "Ανανέωση Ατόμων",
"TaskCleanLogsDescription": "Διαγράφει τα αρχεία καταγραφής που είναι άνω των {0} ημερών.",
"TaskCleanLogs": "Καθαρισμός Καταλόγου Καταγραφής",
"TaskRefreshLibraryDescription": "Σαρώνει την βιβλιοθήκη πολυμέσων σας για νέα αρχεία και αναζωογονεί τα μεταδεδομένα.",
"TaskRefreshLibrary": "Βιβλιοθήκη Σάρωσης Πολυμέσων",
"TaskRefreshChapterImagesDescription": "Δημιουργεί μικρογραφίες για βίντεο με κεφάλαια.",
"TaskRefreshChapterImages": "Εξαγωγή Εικόνων Κεφαλαίου",
"TaskCleanCacheDescription": "Τα διαγραμμένα αρχεία προσωρινής μνήμης που δεν χρειάζονται πλέον από το σύστημα.",
"TaskCleanCache": "Καθαρισμός Καταλόγου Προσωρινής Μνήμης",
"TasksChannelsCategory": "Κανάλια Διαδικτύου",
"TasksApplicationCategory": "Εφαρμογή",
"TasksLibraryCategory": "Βιβλιοθήκη",
"TasksMaintenanceCategory": "Συντήρηση",
"TaskDownloadMissingSubtitlesDescription": "Αναζητήσεις στο διαδίκτυο όπου λείπουν υπότιτλους με βάση τη διαμόρφωση μεταδεδομένων.",
"TaskDownloadMissingSubtitles": "Λήψη υπότιτλων που λείπουν",
"TaskRefreshChannelsDescription": "Ανανεώνει τις πληροφορίες καναλιού στο διαδικτύου.",
"TaskRefreshChannels": "Ανανέωση Καναλιών",
"TaskCleanTranscodeDescription": "Διαγράφει αρχείου διακωδικοποιητή περισσότερο από μία ημέρα.",
"TaskCleanTranscode": "Καθαρισμός Kαταλόγου Διακωδικοποιητή",
"TaskUpdatePluginsDescription": "Κατεβάζει και εγκαθιστά ενημερώσεις για τις προσθήκες που έχουν ρυθμιστεί για αυτόματη ενημέρωση.",
"TaskUpdatePlugins": "Ενημέρωση Προσθηκών",
"TaskRefreshPeopleDescription": "Ενημερώνει μεταδεδομένα για ηθοποιούς και σκηνοθέτες στην βιβλιοθήκη των πολυμέσων σας."
}

@ -1,5 +1,5 @@
{
"HeaderLiveTV": "Suorat lähetykset",
"HeaderLiveTV": "Live-TV",
"NewVersionIsAvailable": "Uusi versio Jellyfin palvelimesta on ladattavissa.",
"NameSeasonUnknown": "Tuntematon Kausi",
"NameSeasonNumber": "Kausi {0}",
@ -12,7 +12,7 @@
"MessageNamedServerConfigurationUpdatedWithValue": "Palvelimen asetusryhmä {0} on päivitetty",
"MessageApplicationUpdatedTo": "Jellyfin palvelin on päivitetty versioon {0}",
"MessageApplicationUpdated": "Jellyfin palvelin on päivitetty",
"Latest": "Viimeisin",
"Latest": "Uusimmat",
"LabelRunningTimeValue": "Toiston kesto: {0}",
"LabelIpAddressValue": "IP-osoite: {0}",
"ItemRemovedWithName": "{0} poistettiin kirjastosta",
@ -41,7 +41,7 @@
"CameraImageUploadedFrom": "Uusi kamerakuva on ladattu {0}",
"Books": "Kirjat",
"AuthenticationSucceededWithUserName": "{0} todennus onnistui",
"Artists": "Esiintyjät",
"Artists": "Artistit",
"Application": "Sovellus",
"AppDeviceValues": "Sovellus: {0}, Laite: {1}",
"Albums": "Albumit",
@ -67,21 +67,21 @@
"UserDownloadingItemWithValues": "{0} lataa {1}",
"UserDeletedWithName": "Käyttäjä {0} poistettu",
"UserCreatedWithName": "Käyttäjä {0} luotu",
"TvShows": "TV-Ohjelmat",
"TvShows": "TV-sarjat",
"Sync": "Synkronoi",
"SubtitleDownloadFailureFromForItem": "Tekstityksen lataaminen epäonnistui {0} - {1}",
"SubtitleDownloadFailureFromForItem": "Tekstitysten lataus ({0} -> {1}) epäonnistui //this string would have to be generated for each provider and movie because of finnish cases, sorry",
"StartupEmbyServerIsLoading": "Jellyfin palvelin latautuu. Kokeile hetken kuluttua uudelleen.",
"Songs": "Kappaleet",
"Shows": "Ohjelmat",
"ServerNameNeedsToBeRestarted": "{0} vaatii uudelleenkäynnistyksen",
"Shows": "Sarjat",
"ServerNameNeedsToBeRestarted": "{0} täytyy käynnistää uudelleen",
"ProviderValue": "Tarjoaja: {0}",
"Plugin": "Liitännäinen",
"NotificationOptionVideoPlaybackStopped": "Videon toisto pysäytetty",
"NotificationOptionVideoPlayback": "Videon toisto aloitettu",
"NotificationOptionUserLockedOut": "Käyttäjä lukittu",
"NotificationOptionVideoPlayback": "Videota toistetaan",
"NotificationOptionUserLockedOut": "Käyttäjä kirjautui ulos",
"NotificationOptionTaskFailed": "Ajastettu tehtävä epäonnistui",
"NotificationOptionServerRestartRequired": "Palvelimen uudelleenkäynnistys vaaditaan",
"NotificationOptionPluginUpdateInstalled": "Lisäosan päivitys asennettu",
"NotificationOptionServerRestartRequired": "Palvelin pitää käynnistää uudelleen",
"NotificationOptionPluginUpdateInstalled": "Liitännäinen päivitetty",
"NotificationOptionPluginUninstalled": "Liitännäinen poistettu",
"NotificationOptionPluginInstalled": "Liitännäinen asennettu",
"NotificationOptionPluginError": "Ongelma liitännäisessä",
@ -90,8 +90,8 @@
"NotificationOptionCameraImageUploaded": "Kameran kuva ladattu",
"NotificationOptionAudioPlaybackStopped": "Äänen toisto lopetettu",
"NotificationOptionAudioPlayback": "Toistetaan ääntä",
"NotificationOptionApplicationUpdateInstalled": "Uusi sovellusversio asennettu",
"NotificationOptionApplicationUpdateAvailable": "Sovelluksesta on uusi versio saatavilla",
"NotificationOptionApplicationUpdateInstalled": "Sovelluspäivitys asennettu",
"NotificationOptionApplicationUpdateAvailable": "Ohjelmistopäivitys saatavilla",
"TasksMaintenanceCategory": "Ylläpito",
"TaskDownloadMissingSubtitlesDescription": "Etsii puuttuvia tekstityksiä videon metadatatietojen pohjalta.",
"TaskDownloadMissingSubtitles": "Lataa puuttuvat tekstitykset",

@ -1,7 +1,7 @@
{
"Albums": "אלבומים",
"AppDeviceValues": "יישום: {0}, מכשיר: {1}",
"Application": "אפליקציה",
"Application": "יישום",
"Artists": "אומנים",
"AuthenticationSucceededWithUserName": "{0} אומת בהצלחה",
"Books": "ספרים",
@ -62,7 +62,7 @@
"NotificationOptionVideoPlayback": "Video playback started",
"NotificationOptionVideoPlaybackStopped": "Video playback stopped",
"Photos": "תמונות",
"Playlists": "רשימות ניגון",
"Playlists": "רשימות הפעלה",
"Plugin": "Plugin",
"PluginInstalledWithName": "{0} was installed",
"PluginUninstalledWithName": "{0} was uninstalled",
@ -92,5 +92,12 @@
"UserStoppedPlayingItemWithValues": "{0} סיים לנגן את {1} על {2}",
"ValueHasBeenAddedToLibrary": "{0} has been added to your media library",
"ValueSpecialEpisodeName": "מיוחד- {0}",
"VersionNumber": "Version {0}"
"VersionNumber": "Version {0}",
"TaskRefreshLibrary": "סרוק ספריית מדיה",
"TaskRefreshChapterImages": "חלץ תמונות פרקים",
"TaskCleanCacheDescription": "מחק קבצי מטמון שלא בשימוש המערכת.",
"TaskCleanCache": "נקה תיקיית מטמון",
"TasksApplicationCategory": "יישום",
"TasksLibraryCategory": "ספרייה",
"TasksMaintenanceCategory": "תחזוקה"
}

@ -96,5 +96,6 @@
"TasksChannelsCategory": "Internett kanaler",
"TasksApplicationCategory": "Applikasjon",
"TasksLibraryCategory": "Bibliotek",
"TasksMaintenanceCategory": "Vedlikehold"
"TasksMaintenanceCategory": "Vedlikehold",
"TaskCleanCache": "Tøm buffer katalog"
}

@ -92,5 +92,27 @@
"UserStoppedPlayingItemWithValues": "{0} zakończył odtwarzanie {1} na {2}",
"ValueHasBeenAddedToLibrary": "{0} został dodany do biblioteki mediów",
"ValueSpecialEpisodeName": "Specjalne - {0}",
"VersionNumber": "Wersja {0}"
"VersionNumber": "Wersja {0}",
"TaskDownloadMissingSubtitlesDescription": "Przeszukuje internet w poszukiwaniu brakujących napisów w oparciu o konfigurację metadanych.",
"TaskDownloadMissingSubtitles": "Pobierz brakujące napisy",
"TaskRefreshChannelsDescription": "Odświeża informacje o kanałach internetowych.",
"TaskRefreshChannels": "Odśwież kanały",
"TaskCleanTranscodeDescription": "Usuwa transkodowane pliki starsze niż 1 dzień.",
"TaskCleanTranscode": "Wyczyść folder transkodowania",
"TaskUpdatePluginsDescription": "Pobiera i instaluje aktualizacje dla pluginów które są skonfigurowane do automatycznej aktualizacji.",
"TaskUpdatePlugins": "Aktualizuj pluginy",
"TaskRefreshPeopleDescription": "Odświeża metadane o aktorów i reżyserów w Twojej bibliotece mediów.",
"TaskRefreshPeople": "Odśwież obsadę",
"TaskCleanLogsDescription": "Kasuje pliki logów starsze niż {0} dni.",
"TaskCleanLogs": "Wyczyść folder logów",
"TaskRefreshLibraryDescription": "Skanuje Twoją bibliotekę mediów dla nowych plików i odświeżenia metadanych.",
"TaskRefreshLibrary": "Skanuj bibliotekę mediów",
"TaskRefreshChapterImagesDescription": "Tworzy miniatury dla filmów posiadających rozdziały.",
"TaskRefreshChapterImages": "Wydobądź grafiki rozdziałów",
"TaskCleanCacheDescription": "Usuwa niepotrzebne i przestarzałe pliki cache.",
"TaskCleanCache": "Wyczyść folder Cache",
"TasksChannelsCategory": "Kanały internetowe",
"TasksApplicationCategory": "Aplikacja",
"TasksLibraryCategory": "Biblioteka",
"TasksMaintenanceCategory": "Konserwacja"
}

@ -9,7 +9,7 @@
"Channels": "Kanaler",
"ChapterNameValue": "Kapitel {0}",
"Collections": "Samlingar",
"DeviceOfflineWithName": "{0} har tappat anslutningen",
"DeviceOfflineWithName": "{0} har kopplat från",
"DeviceOnlineWithName": "{0} är ansluten",
"FailedLoginAttemptWithUserName": "Misslyckat inloggningsförsök från {0}",
"Favorites": "Favoriter",
@ -50,7 +50,7 @@
"NotificationOptionAudioPlayback": "Ljuduppspelning har påbörjats",
"NotificationOptionAudioPlaybackStopped": "Ljuduppspelning stoppades",
"NotificationOptionCameraImageUploaded": "Kamerabild har laddats upp",
"NotificationOptionInstallationFailed": "Fel vid installation",
"NotificationOptionInstallationFailed": "Installationen misslyckades",
"NotificationOptionNewLibraryContent": "Nytt innehåll har lagts till",
"NotificationOptionPluginError": "Fel uppstod med tillägget",
"NotificationOptionPluginInstalled": "Tillägg har installerats",
@ -113,5 +113,6 @@
"TasksChannelsCategory": "Internetkanaler",
"TasksApplicationCategory": "Applikation",
"TasksLibraryCategory": "Bibliotek",
"TasksMaintenanceCategory": "Underhåll"
"TasksMaintenanceCategory": "Underhåll",
"TaskRefreshPeople": "Uppdatera Personer"
}

@ -9,8 +9,6 @@ namespace Emby.Server.Implementations
/// </summary>
public class ServerApplicationPaths : BaseApplicationPaths, IServerApplicationPaths
{
private string _internalMetadataPath;
/// <summary>
/// Initializes a new instance of the <see cref="ServerApplicationPaths" /> class.
/// </summary>
@ -27,6 +25,7 @@ namespace Emby.Server.Implementations
cacheDirectoryPath,
webDirectoryPath)
{
InternalMetadataPath = DefaultInternalMetadataPath;
}
/// <summary>
@ -98,12 +97,11 @@ namespace Emby.Server.Implementations
/// <value>The user configuration directory path.</value>
public string UserConfigurationDirectoryPath => Path.Combine(ConfigurationDirectoryPath, "users");
/// <inheritdoc/>
public string DefaultInternalMetadataPath => Path.Combine(ProgramDataPath, "metadata");
/// <inheritdoc />
public string InternalMetadataPath
{
get => _internalMetadataPath ?? (_internalMetadataPath = Path.Combine(DataPath, "metadata"));
set => _internalMetadataPath = value;
}
public string InternalMetadataPath { get; set; }
/// <inheritdoc />
public string VirtualInternalMetadataPath { get; } = "%MetadataPath%";

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using MediaBrowser.Common.Extensions;
namespace Emby.Server.Implementations.Services
{
@ -81,7 +82,7 @@ namespace Emby.Server.Implementations.Services
if (propertySerializerEntry.PropertyType == typeof(bool))
{
//InputExtensions.cs#530 MVC Checkbox helper emits extra hidden input field, generating 2 values, first is the real value
propertyTextValue = LeftPart(propertyTextValue, ',');
propertyTextValue = StringExtensions.LeftPart(propertyTextValue, ',').ToString();
}
var value = propertySerializerEntry.PropertyParseStringFn(propertyTextValue);
@ -95,19 +96,6 @@ namespace Emby.Server.Implementations.Services
return instance;
}
public static string LeftPart(string strVal, char needle)
{
if (strVal == null)
{
return null;
}
var pos = strVal.IndexOf(needle);
return pos == -1
? strVal
: strVal.Substring(0, pos);
}
}
internal static class TypeAccessor

@ -1,4 +1,5 @@
using System;
using MediaBrowser.Common.Extensions;
namespace Emby.Server.Implementations.Services
{
@ -13,25 +14,12 @@ namespace Emby.Server.Implementations.Services
public static string GetMethodName(this Type type)
{
var typeName = type.FullName != null // can be null, e.g. generic types
? LeftPart(type.FullName, "[[") // Generic Fullname
.Replace(type.Namespace + ".", string.Empty) // Trim Namespaces
.Replace("+", ".") // Convert nested into normal type
? StringExtensions.LeftPart(type.FullName, "[[", StringComparison.Ordinal).ToString() // Generic Fullname
.Replace(type.Namespace + ".", string.Empty, StringComparison.Ordinal) // Trim Namespaces
.Replace("+", ".", StringComparison.Ordinal) // Convert nested into normal type
: type.Name;
return type.IsGenericParameter ? "'" + typeName : typeName;
}
private static string LeftPart(string strVal, string needle)
{
if (strVal == null)
{
return null;
}
var pos = strVal.IndexOf(needle, StringComparison.OrdinalIgnoreCase);
return pos == -1
? strVal
: strVal.Substring(0, pos);
}
}
}

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Mime;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
@ -222,14 +223,14 @@ namespace Emby.Server.Implementations.SocketSharp
pi = pi.Slice(1);
}
format = LeftPart(pi, '/');
format = pi.LeftPart('/');
if (format.Length > FormatMaxLength)
{
return null;
}
}
format = LeftPart(format, '.');
format = format.LeftPart('.');
if (format.Contains("json", StringComparison.OrdinalIgnoreCase))
{
return "application/json";
@ -241,16 +242,5 @@ namespace Emby.Server.Implementations.SocketSharp
return null;
}
public static ReadOnlySpan<char> LeftPart(ReadOnlySpan<char> strVal, char needle)
{
if (strVal == null)
{
return null;
}
var pos = strVal.IndexOf(needle);
return pos == -1 ? strVal : strVal.Slice(0, pos);
}
}
}

@ -1,3 +1,4 @@
using System.Net.Mime;
using Microsoft.AspNetCore.Mvc;
namespace Jellyfin.Api
@ -7,6 +8,7 @@ namespace Jellyfin.Api
/// </summary>
[ApiController]
[Route("[controller]")]
[Produces(MediaTypeNames.Application.Json)]
public class BaseJellyfinApiController : ControllerBase
{
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,208 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Artwork
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Artwork()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Artwork CreateArtworkUnsafe()
{
return new Artwork();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="path"></param>
/// <param name="kind"></param>
/// <param name="_metadata0"></param>
/// <param name="_personrole1"></param>
public Artwork(string path, global::Jellyfin.Data.Enums.ArtKind kind, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.PersonRole _personrole1)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
this.Path = path;
this.Kind = kind;
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.Artwork.Add(this);
if (_personrole1 == null) throw new ArgumentNullException(nameof(_personrole1));
_personrole1.Artwork = this;
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="path"></param>
/// <param name="kind"></param>
/// <param name="_metadata0"></param>
/// <param name="_personrole1"></param>
public static Artwork Create(string path, global::Jellyfin.Data.Enums.ArtKind kind, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.PersonRole _personrole1)
{
return new Artwork(path, kind, _metadata0, _personrole1);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Path
/// </summary>
protected string _Path;
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before setting.
/// </summary>
partial void SetPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before returning.
/// </summary>
partial void GetPath(ref string result);
/// <summary>
/// Required, Max length = 65535
/// </summary>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Path
{
get
{
string value = _Path;
GetPath(ref value);
return (_Path = value);
}
set
{
string oldValue = _Path;
SetPath(oldValue, ref value);
if (oldValue != value)
{
_Path = value;
}
}
}
/// <summary>
/// Backing field for Kind
/// </summary>
internal global::Jellyfin.Data.Enums.ArtKind _Kind;
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before setting.
/// </summary>
partial void SetKind(global::Jellyfin.Data.Enums.ArtKind oldValue, ref global::Jellyfin.Data.Enums.ArtKind newValue);
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before returning.
/// </summary>
partial void GetKind(ref global::Jellyfin.Data.Enums.ArtKind result);
/// <summary>
/// Indexed, Required
/// </summary>
[Required]
public global::Jellyfin.Data.Enums.ArtKind Kind
{
get
{
global::Jellyfin.Data.Enums.ArtKind value = _Kind;
GetKind(ref value);
return (_Kind = value);
}
set
{
global::Jellyfin.Data.Enums.ArtKind oldValue = _Kind;
SetKind(oldValue, ref value);
if (oldValue != value)
{
_Kind = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

@ -0,0 +1,84 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Book: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Book(): base()
{
BookMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.BookMetadata>();
Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Book CreateBookUnsafe()
{
return new Book();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public Book(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
this.BookMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.BookMetadata>();
this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static Book Create(Guid urlid, DateTime dateadded)
{
return new Book(urlid, dateadded);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.BookMetadata> BookMetadata { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
}
}

@ -0,0 +1,123 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class BookMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected BookMetadata(): base()
{
Publishers = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static BookMetadata CreateBookMetadataUnsafe()
{
return new BookMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_book0"></param>
public BookMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Book _book0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_book0 == null) throw new ArgumentNullException(nameof(_book0));
_book0.BookMetadata.Add(this);
this.Publishers = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_book0"></param>
public static BookMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Book _book0)
{
return new BookMetadata(title, language, dateadded, datemodified, _book0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for ISBN
/// </summary>
protected long? _ISBN;
/// <summary>
/// When provided in a partial class, allows value of ISBN to be changed before setting.
/// </summary>
partial void SetISBN(long? oldValue, ref long? newValue);
/// <summary>
/// When provided in a partial class, allows value of ISBN to be changed before returning.
/// </summary>
partial void GetISBN(ref long? result);
public long? ISBN
{
get
{
long? value = _ISBN;
GetISBN(ref value);
return (_ISBN = value);
}
set
{
long? oldValue = _ISBN;
SetISBN(oldValue, ref value);
if (oldValue != value)
{
_ISBN = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.Company> Publishers { get; protected set; }
}
}

@ -0,0 +1,274 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Chapter
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Chapter()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Chapter CreateChapterUnsafe()
{
return new Chapter();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="timestart"></param>
/// <param name="_release0"></param>
public Chapter(string language, long timestart, global::Jellyfin.Data.Entities.Release _release0)
{
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
this.TimeStart = timestart;
if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
_release0.Chapters.Add(this);
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="timestart"></param>
/// <param name="_release0"></param>
public static Chapter Create(string language, long timestart, global::Jellyfin.Data.Entities.Release _release0)
{
return new Chapter(language, timestart, _release0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
/// <summary>
/// Backing field for Language
/// </summary>
protected string _Language;
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before setting.
/// </summary>
partial void SetLanguage(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before returning.
/// </summary>
partial void GetLanguage(ref string result);
/// <summary>
/// Required, Min length = 3, Max length = 3
/// ISO-639-3 3-character language codes
/// </summary>
[Required]
[MinLength(3)]
[MaxLength(3)]
[StringLength(3)]
public string Language
{
get
{
string value = _Language;
GetLanguage(ref value);
return (_Language = value);
}
set
{
string oldValue = _Language;
SetLanguage(oldValue, ref value);
if (oldValue != value)
{
_Language = value;
}
}
}
/// <summary>
/// Backing field for TimeStart
/// </summary>
protected long _TimeStart;
/// <summary>
/// When provided in a partial class, allows value of TimeStart to be changed before setting.
/// </summary>
partial void SetTimeStart(long oldValue, ref long newValue);
/// <summary>
/// When provided in a partial class, allows value of TimeStart to be changed before returning.
/// </summary>
partial void GetTimeStart(ref long result);
/// <summary>
/// Required
/// </summary>
[Required]
public long TimeStart
{
get
{
long value = _TimeStart;
GetTimeStart(ref value);
return (_TimeStart = value);
}
set
{
long oldValue = _TimeStart;
SetTimeStart(oldValue, ref value);
if (oldValue != value)
{
_TimeStart = value;
}
}
}
/// <summary>
/// Backing field for TimeEnd
/// </summary>
protected long? _TimeEnd;
/// <summary>
/// When provided in a partial class, allows value of TimeEnd to be changed before setting.
/// </summary>
partial void SetTimeEnd(long? oldValue, ref long? newValue);
/// <summary>
/// When provided in a partial class, allows value of TimeEnd to be changed before returning.
/// </summary>
partial void GetTimeEnd(ref long? result);
public long? TimeEnd
{
get
{
long? value = _TimeEnd;
GetTimeEnd(ref value);
return (_TimeEnd = value);
}
set
{
long? oldValue = _TimeEnd;
SetTimeEnd(oldValue, ref value);
if (oldValue != value)
{
_TimeEnd = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

@ -0,0 +1,131 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Collection
{
partial void Init();
/// <summary>
/// Default constructor
/// </summary>
public Collection()
{
CollectionItem = new System.Collections.Generic.LinkedList<global::Jellyfin.Data.Entities.CollectionItem>();
Init();
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.CollectionItem> CollectionItem { get; protected set; }
}
}

@ -0,0 +1,151 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class CollectionItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CollectionItem()
{
// NOTE: This class has one-to-one associations with CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CollectionItem CreateCollectionItemUnsafe()
{
return new CollectionItem();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="_collection0"></param>
/// <param name="_collectionitem1"></param>
/// <param name="_collectionitem2"></param>
public CollectionItem(global::Jellyfin.Data.Entities.Collection _collection0, global::Jellyfin.Data.Entities.CollectionItem _collectionitem1, global::Jellyfin.Data.Entities.CollectionItem _collectionitem2)
{
// NOTE: This class has one-to-one associations with CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
if (_collection0 == null) throw new ArgumentNullException(nameof(_collection0));
_collection0.CollectionItem.Add(this);
if (_collectionitem1 == null) throw new ArgumentNullException(nameof(_collectionitem1));
_collectionitem1.Next = this;
if (_collectionitem2 == null) throw new ArgumentNullException(nameof(_collectionitem2));
_collectionitem2.Previous = this;
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="_collection0"></param>
/// <param name="_collectionitem1"></param>
/// <param name="_collectionitem2"></param>
public static CollectionItem Create(global::Jellyfin.Data.Entities.Collection _collection0, global::Jellyfin.Data.Entities.CollectionItem _collectionitem1, global::Jellyfin.Data.Entities.CollectionItem _collectionitem2)
{
return new CollectionItem(_collection0, _collectionitem1, _collectionitem2);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
public virtual global::Jellyfin.Data.Entities.LibraryItem LibraryItem { get; set; }
/// <remarks>
/// TODO check if this properly updated dependant and has the proper principal relationship
/// </remarks>
public virtual global::Jellyfin.Data.Entities.CollectionItem Next { get; set; }
/// <remarks>
/// TODO check if this properly updated dependant and has the proper principal relationship
/// </remarks>
public virtual global::Jellyfin.Data.Entities.CollectionItem Previous { get; set; }
}
}

@ -0,0 +1,147 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Company
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Company()
{
CompanyMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CompanyMetadata>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Company CreateCompanyUnsafe()
{
return new Company();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="_moviemetadata0"></param>
/// <param name="_seriesmetadata1"></param>
/// <param name="_musicalbummetadata2"></param>
/// <param name="_bookmetadata3"></param>
/// <param name="_company4"></param>
public Company(global::Jellyfin.Data.Entities.MovieMetadata _moviemetadata0, global::Jellyfin.Data.Entities.SeriesMetadata _seriesmetadata1, global::Jellyfin.Data.Entities.MusicAlbumMetadata _musicalbummetadata2, global::Jellyfin.Data.Entities.BookMetadata _bookmetadata3, global::Jellyfin.Data.Entities.Company _company4)
{
if (_moviemetadata0 == null) throw new ArgumentNullException(nameof(_moviemetadata0));
_moviemetadata0.Studios.Add(this);
if (_seriesmetadata1 == null) throw new ArgumentNullException(nameof(_seriesmetadata1));
_seriesmetadata1.Networks.Add(this);
if (_musicalbummetadata2 == null) throw new ArgumentNullException(nameof(_musicalbummetadata2));
_musicalbummetadata2.Labels.Add(this);
if (_bookmetadata3 == null) throw new ArgumentNullException(nameof(_bookmetadata3));
_bookmetadata3.Publishers.Add(this);
if (_company4 == null) throw new ArgumentNullException(nameof(_company4));
_company4.Parent = this;
this.CompanyMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CompanyMetadata>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="_moviemetadata0"></param>
/// <param name="_seriesmetadata1"></param>
/// <param name="_musicalbummetadata2"></param>
/// <param name="_bookmetadata3"></param>
/// <param name="_company4"></param>
public static Company Create(global::Jellyfin.Data.Entities.MovieMetadata _moviemetadata0, global::Jellyfin.Data.Entities.SeriesMetadata _seriesmetadata1, global::Jellyfin.Data.Entities.MusicAlbumMetadata _musicalbummetadata2, global::Jellyfin.Data.Entities.BookMetadata _bookmetadata3, global::Jellyfin.Data.Entities.Company _company4)
{
return new Company(_moviemetadata0, _seriesmetadata1, _musicalbummetadata2, _bookmetadata3, _company4);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.CompanyMetadata> CompanyMetadata { get; protected set; }
public virtual global::Jellyfin.Data.Entities.Company Parent { get; set; }
}
}

@ -0,0 +1,234 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class CompanyMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CompanyMetadata(): base()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CompanyMetadata CreateCompanyMetadataUnsafe()
{
return new CompanyMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_company0"></param>
public CompanyMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Company _company0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_company0 == null) throw new ArgumentNullException(nameof(_company0));
_company0.CompanyMetadata.Add(this);
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_company0"></param>
public static CompanyMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Company _company0)
{
return new CompanyMetadata(title, language, dateadded, datemodified, _company0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Description
/// </summary>
protected string _Description;
/// <summary>
/// When provided in a partial class, allows value of Description to be changed before setting.
/// </summary>
partial void SetDescription(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Description to be changed before returning.
/// </summary>
partial void GetDescription(ref string result);
/// <summary>
/// Max length = 65535
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string Description
{
get
{
string value = _Description;
GetDescription(ref value);
return (_Description = value);
}
set
{
string oldValue = _Description;
SetDescription(oldValue, ref value);
if (oldValue != value)
{
_Description = value;
}
}
}
/// <summary>
/// Backing field for Headquarters
/// </summary>
protected string _Headquarters;
/// <summary>
/// When provided in a partial class, allows value of Headquarters to be changed before setting.
/// </summary>
partial void SetHeadquarters(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Headquarters to be changed before returning.
/// </summary>
partial void GetHeadquarters(ref string result);
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string Headquarters
{
get
{
string value = _Headquarters;
GetHeadquarters(ref value);
return (_Headquarters = value);
}
set
{
string oldValue = _Headquarters;
SetHeadquarters(oldValue, ref value);
if (oldValue != value)
{
_Headquarters = value;
}
}
}
/// <summary>
/// Backing field for Country
/// </summary>
protected string _Country;
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before setting.
/// </summary>
partial void SetCountry(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before returning.
/// </summary>
partial void GetCountry(ref string result);
/// <summary>
/// Max length = 2
/// </summary>
[MaxLength(2)]
[StringLength(2)]
public string Country
{
get
{
string value = _Country;
GetCountry(ref value);
return (_Country = value);
}
set
{
string oldValue = _Country;
SetCountry(oldValue, ref value);
if (oldValue != value)
{
_Country = value;
}
}
}
/// <summary>
/// Backing field for Homepage
/// </summary>
protected string _Homepage;
/// <summary>
/// When provided in a partial class, allows value of Homepage to be changed before setting.
/// </summary>
partial void SetHomepage(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Homepage to be changed before returning.
/// </summary>
partial void GetHomepage(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Homepage
{
get
{
string value = _Homepage;
GetHomepage(ref value);
return (_Homepage = value);
}
set
{
string oldValue = _Homepage;
SetHomepage(oldValue, ref value);
if (oldValue != value)
{
_Homepage = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

@ -0,0 +1,84 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class CustomItem: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CustomItem(): base()
{
CustomItemMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CustomItemMetadata>();
Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CustomItem CreateCustomItemUnsafe()
{
return new CustomItem();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public CustomItem(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
this.CustomItemMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CustomItemMetadata>();
this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static CustomItem Create(Guid urlid, DateTime dateadded)
{
return new CustomItem(urlid, dateadded);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.CustomItemMetadata> CustomItemMetadata { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
}
}

@ -0,0 +1,86 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class CustomItemMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CustomItemMetadata(): base()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CustomItemMetadata CreateCustomItemMetadataUnsafe()
{
return new CustomItemMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_customitem0"></param>
public CustomItemMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.CustomItem _customitem0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_customitem0 == null) throw new ArgumentNullException(nameof(_customitem0));
_customitem0.CustomItemMetadata.Add(this);
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_customitem0"></param>
public static CustomItemMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.CustomItem _customitem0)
{
return new CustomItemMetadata(title, language, dateadded, datemodified, _customitem0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

@ -0,0 +1,127 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Episode: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Episode(): base()
{
// NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
EpisodeMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.EpisodeMetadata>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Episode CreateEpisodeUnsafe()
{
return new Episode();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
/// <param name="_season0"></param>
public Episode(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Season _season0)
{
// NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
this.UrlId = urlid;
if (_season0 == null) throw new ArgumentNullException(nameof(_season0));
_season0.Episodes.Add(this);
this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
this.EpisodeMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.EpisodeMetadata>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
/// <param name="_season0"></param>
public static Episode Create(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Season _season0)
{
return new Episode(urlid, dateadded, _season0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for EpisodeNumber
/// </summary>
protected int? _EpisodeNumber;
/// <summary>
/// When provided in a partial class, allows value of EpisodeNumber to be changed before setting.
/// </summary>
partial void SetEpisodeNumber(int? oldValue, ref int? newValue);
/// <summary>
/// When provided in a partial class, allows value of EpisodeNumber to be changed before returning.
/// </summary>
partial void GetEpisodeNumber(ref int? result);
public int? EpisodeNumber
{
get
{
int? value = _EpisodeNumber;
GetEpisodeNumber(ref value);
return (_EpisodeNumber = value);
}
set
{
int? oldValue = _EpisodeNumber;
SetEpisodeNumber(oldValue, ref value);
if (oldValue != value)
{
_EpisodeNumber = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.EpisodeMetadata> EpisodeMetadata { get; protected set; }
}
}

@ -0,0 +1,197 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class EpisodeMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected EpisodeMetadata(): base()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static EpisodeMetadata CreateEpisodeMetadataUnsafe()
{
return new EpisodeMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_episode0"></param>
public EpisodeMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Episode _episode0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_episode0 == null) throw new ArgumentNullException(nameof(_episode0));
_episode0.EpisodeMetadata.Add(this);
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_episode0"></param>
public static EpisodeMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Episode _episode0)
{
return new EpisodeMetadata(title, language, dateadded, datemodified, _episode0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Outline
/// </summary>
protected string _Outline;
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before setting.
/// </summary>
partial void SetOutline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before returning.
/// </summary>
partial void GetOutline(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Outline
{
get
{
string value = _Outline;
GetOutline(ref value);
return (_Outline = value);
}
set
{
string oldValue = _Outline;
SetOutline(oldValue, ref value);
if (oldValue != value)
{
_Outline = value;
}
}
}
/// <summary>
/// Backing field for Plot
/// </summary>
protected string _Plot;
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before setting.
/// </summary>
partial void SetPlot(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before returning.
/// </summary>
partial void GetPlot(ref string result);
/// <summary>
/// Max length = 65535
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string Plot
{
get
{
string value = _Plot;
GetPlot(ref value);
return (_Plot = value);
}
set
{
string oldValue = _Plot;
SetPlot(oldValue, ref value);
if (oldValue != value)
{
_Plot = value;
}
}
}
/// <summary>
/// Backing field for Tagline
/// </summary>
protected string _Tagline;
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before setting.
/// </summary>
partial void SetTagline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before returning.
/// </summary>
partial void GetTagline(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Tagline
{
get
{
string value = _Tagline;
GetTagline(ref value);
return (_Tagline = value);
}
set
{
string oldValue = _Tagline;
SetTagline(oldValue, ref value);
if (oldValue != value)
{
_Tagline = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

@ -0,0 +1,163 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Genre
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Genre()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Genre CreateGenreUnsafe()
{
return new Genre();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
/// <param name="_metadata0"></param>
public Genre(string name, global::Jellyfin.Data.Entities.Metadata _metadata0)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.Genres.Add(this);
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
/// <param name="_metadata0"></param>
public static Genre Create(string name, global::Jellyfin.Data.Entities.Metadata _metadata0)
{
return new Genre(name, _metadata0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
internal string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Indexed, Required, Max length = 255
/// </summary>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

@ -0,0 +1,115 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Group
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Group()
{
GroupPermissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>();
ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>();
Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Group CreateGroupUnsafe()
{
return new Group();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
/// <param name="_user0"></param>
public Group(string name, global::Jellyfin.Data.Entities.User _user0)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
_user0.Groups.Add(this);
this.GroupPermissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>();
this.ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>();
this.Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
/// <param name="_user0"></param>
public static Group Create(string name, global::Jellyfin.Data.Entities.User _user0)
{
return new Group(name, _user0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id { get; protected set; }
/// <summary>
/// Required, Max length = 255
/// </summary>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string Name { get; set; }
/// <summary>
/// Concurrency token
/// </summary>
[Timestamp]
public Byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.Permission> GroupPermissions { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.ProviderMapping> ProviderMappings { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Preference> Preferences { get; protected set; }
}
}

@ -0,0 +1,158 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Library
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Library()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Library CreateLibraryUnsafe()
{
return new Library();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
public Library(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
public static Library Create(string name)
{
return new Library(name);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Required, Max length = 1024
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

@ -0,0 +1,180 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public abstract partial class LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to being abstract.
/// </summary>
protected LibraryItem()
{
Init();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
protected LibraryItem(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
Init();
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for UrlId
/// </summary>
internal Guid _UrlId;
/// <summary>
/// When provided in a partial class, allows value of UrlId to be changed before setting.
/// </summary>
partial void SetUrlId(Guid oldValue, ref Guid newValue);
/// <summary>
/// When provided in a partial class, allows value of UrlId to be changed before returning.
/// </summary>
partial void GetUrlId(ref Guid result);
/// <summary>
/// Indexed, Required
/// This is whats gets displayed in the Urls and API requests. This could also be a string.
/// </summary>
[Required]
public Guid UrlId
{
get
{
Guid value = _UrlId;
GetUrlId(ref value);
return (_UrlId = value);
}
set
{
Guid oldValue = _UrlId;
SetUrlId(oldValue, ref value);
if (oldValue != value)
{
_UrlId = value;
}
}
}
/// <summary>
/// Backing field for DateAdded
/// </summary>
protected DateTime _DateAdded;
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before setting.
/// </summary>
partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before returning.
/// </summary>
partial void GetDateAdded(ref DateTime result);
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateAdded
{
get
{
DateTime value = _DateAdded;
GetDateAdded(ref value);
return (_DateAdded = value);
}
internal set
{
DateTime oldValue = _DateAdded;
SetDateAdded(oldValue, ref value);
if (oldValue != value)
{
_DateAdded = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
public virtual global::Jellyfin.Data.Entities.LibraryRoot LibraryRoot { get; set; }
}
}

@ -0,0 +1,202 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class LibraryRoot
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected LibraryRoot()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static LibraryRoot CreateLibraryRootUnsafe()
{
return new LibraryRoot();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="path">Absolute Path</param>
public LibraryRoot(string path)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
this.Path = path;
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="path">Absolute Path</param>
public static LibraryRoot Create(string path)
{
return new LibraryRoot(path);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Path
/// </summary>
protected string _Path;
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before setting.
/// </summary>
partial void SetPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before returning.
/// </summary>
partial void GetPath(ref string result);
/// <summary>
/// Required, Max length = 65535
/// Absolute Path
/// </summary>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Path
{
get
{
string value = _Path;
GetPath(ref value);
return (_Path = value);
}
set
{
string oldValue = _Path;
SetPath(oldValue, ref value);
if (oldValue != value)
{
_Path = value;
}
}
}
/// <summary>
/// Backing field for NetworkPath
/// </summary>
protected string _NetworkPath;
/// <summary>
/// When provided in a partial class, allows value of NetworkPath to be changed before setting.
/// </summary>
partial void SetNetworkPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of NetworkPath to be changed before returning.
/// </summary>
partial void GetNetworkPath(ref string result);
/// <summary>
/// Max length = 65535
/// Absolute network path, for example for transcoding sattelites.
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string NetworkPath
{
get
{
string value = _NetworkPath;
GetNetworkPath(ref value);
return (_NetworkPath = value);
}
set
{
string oldValue = _NetworkPath;
SetNetworkPath(oldValue, ref value);
if (oldValue != value)
{
_NetworkPath = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
public virtual global::Jellyfin.Data.Entities.Library Library { get; set; }
}
}

@ -0,0 +1,209 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MediaFile
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MediaFile()
{
MediaFileStreams = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFileStream>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MediaFile CreateMediaFileUnsafe()
{
return new MediaFile();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="path">Relative to the LibraryRoot</param>
/// <param name="kind"></param>
/// <param name="_release0"></param>
public MediaFile(string path, global::Jellyfin.Data.Enums.MediaFileKind kind, global::Jellyfin.Data.Entities.Release _release0)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
this.Path = path;
this.Kind = kind;
if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
_release0.MediaFiles.Add(this);
this.MediaFileStreams = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFileStream>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="path">Relative to the LibraryRoot</param>
/// <param name="kind"></param>
/// <param name="_release0"></param>
public static MediaFile Create(string path, global::Jellyfin.Data.Enums.MediaFileKind kind, global::Jellyfin.Data.Entities.Release _release0)
{
return new MediaFile(path, kind, _release0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Path
/// </summary>
protected string _Path;
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before setting.
/// </summary>
partial void SetPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before returning.
/// </summary>
partial void GetPath(ref string result);
/// <summary>
/// Required, Max length = 65535
/// Relative to the LibraryRoot
/// </summary>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Path
{
get
{
string value = _Path;
GetPath(ref value);
return (_Path = value);
}
set
{
string oldValue = _Path;
SetPath(oldValue, ref value);
if (oldValue != value)
{
_Path = value;
}
}
}
/// <summary>
/// Backing field for Kind
/// </summary>
protected global::Jellyfin.Data.Enums.MediaFileKind _Kind;
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before setting.
/// </summary>
partial void SetKind(global::Jellyfin.Data.Enums.MediaFileKind oldValue, ref global::Jellyfin.Data.Enums.MediaFileKind newValue);
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before returning.
/// </summary>
partial void GetKind(ref global::Jellyfin.Data.Enums.MediaFileKind result);
/// <summary>
/// Required
/// </summary>
[Required]
public global::Jellyfin.Data.Enums.MediaFileKind Kind
{
get
{
global::Jellyfin.Data.Enums.MediaFileKind value = _Kind;
GetKind(ref value);
return (_Kind = value);
}
set
{
global::Jellyfin.Data.Enums.MediaFileKind oldValue = _Kind;
SetKind(oldValue, ref value);
if (oldValue != value)
{
_Kind = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.MediaFileStream> MediaFileStreams { get; protected set; }
}
}

@ -0,0 +1,160 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MediaFileStream
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MediaFileStream()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MediaFileStream CreateMediaFileStreamUnsafe()
{
return new MediaFileStream();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="streamnumber"></param>
/// <param name="_mediafile0"></param>
public MediaFileStream(int streamnumber, global::Jellyfin.Data.Entities.MediaFile _mediafile0)
{
this.StreamNumber = streamnumber;
if (_mediafile0 == null) throw new ArgumentNullException(nameof(_mediafile0));
_mediafile0.MediaFileStreams.Add(this);
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="streamnumber"></param>
/// <param name="_mediafile0"></param>
public static MediaFileStream Create(int streamnumber, global::Jellyfin.Data.Entities.MediaFile _mediafile0)
{
return new MediaFileStream(streamnumber, _mediafile0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for StreamNumber
/// </summary>
protected int _StreamNumber;
/// <summary>
/// When provided in a partial class, allows value of StreamNumber to be changed before setting.
/// </summary>
partial void SetStreamNumber(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of StreamNumber to be changed before returning.
/// </summary>
partial void GetStreamNumber(ref int result);
/// <summary>
/// Required
/// </summary>
[Required]
public int StreamNumber
{
get
{
int value = _StreamNumber;
GetStreamNumber(ref value);
return (_StreamNumber = value);
}
set
{
int oldValue = _StreamNumber;
SetStreamNumber(oldValue, ref value);
if (oldValue != value)
{
_StreamNumber = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

@ -0,0 +1,385 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public abstract partial class Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to being abstract.
/// </summary>
protected Metadata()
{
PersonRoles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PersonRole>();
Genres = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Genre>();
Artwork = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Artwork>();
Ratings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Rating>();
Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
Init();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
protected Metadata(string title, string language, DateTime dateadded, DateTime datemodified)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
this.PersonRoles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PersonRole>();
this.Genres = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Genre>();
this.Artwork = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Artwork>();
this.Ratings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Rating>();
this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
Init();
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Title
/// </summary>
protected string _Title;
/// <summary>
/// When provided in a partial class, allows value of Title to be changed before setting.
/// </summary>
partial void SetTitle(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Title to be changed before returning.
/// </summary>
partial void GetTitle(ref string result);
/// <summary>
/// Required, Max length = 1024
/// The title or name of the object
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Title
{
get
{
string value = _Title;
GetTitle(ref value);
return (_Title = value);
}
set
{
string oldValue = _Title;
SetTitle(oldValue, ref value);
if (oldValue != value)
{
_Title = value;
}
}
}
/// <summary>
/// Backing field for OriginalTitle
/// </summary>
protected string _OriginalTitle;
/// <summary>
/// When provided in a partial class, allows value of OriginalTitle to be changed before setting.
/// </summary>
partial void SetOriginalTitle(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of OriginalTitle to be changed before returning.
/// </summary>
partial void GetOriginalTitle(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string OriginalTitle
{
get
{
string value = _OriginalTitle;
GetOriginalTitle(ref value);
return (_OriginalTitle = value);
}
set
{
string oldValue = _OriginalTitle;
SetOriginalTitle(oldValue, ref value);
if (oldValue != value)
{
_OriginalTitle = value;
}
}
}
/// <summary>
/// Backing field for SortTitle
/// </summary>
protected string _SortTitle;
/// <summary>
/// When provided in a partial class, allows value of SortTitle to be changed before setting.
/// </summary>
partial void SetSortTitle(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of SortTitle to be changed before returning.
/// </summary>
partial void GetSortTitle(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string SortTitle
{
get
{
string value = _SortTitle;
GetSortTitle(ref value);
return (_SortTitle = value);
}
set
{
string oldValue = _SortTitle;
SetSortTitle(oldValue, ref value);
if (oldValue != value)
{
_SortTitle = value;
}
}
}
/// <summary>
/// Backing field for Language
/// </summary>
protected string _Language;
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before setting.
/// </summary>
partial void SetLanguage(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before returning.
/// </summary>
partial void GetLanguage(ref string result);
/// <summary>
/// Required, Min length = 3, Max length = 3
/// ISO-639-3 3-character language codes
/// </summary>
[Required]
[MinLength(3)]
[MaxLength(3)]
[StringLength(3)]
public string Language
{
get
{
string value = _Language;
GetLanguage(ref value);
return (_Language = value);
}
set
{
string oldValue = _Language;
SetLanguage(oldValue, ref value);
if (oldValue != value)
{
_Language = value;
}
}
}
/// <summary>
/// Backing field for ReleaseDate
/// </summary>
protected DateTimeOffset? _ReleaseDate;
/// <summary>
/// When provided in a partial class, allows value of ReleaseDate to be changed before setting.
/// </summary>
partial void SetReleaseDate(DateTimeOffset? oldValue, ref DateTimeOffset? newValue);
/// <summary>
/// When provided in a partial class, allows value of ReleaseDate to be changed before returning.
/// </summary>
partial void GetReleaseDate(ref DateTimeOffset? result);
public DateTimeOffset? ReleaseDate
{
get
{
DateTimeOffset? value = _ReleaseDate;
GetReleaseDate(ref value);
return (_ReleaseDate = value);
}
set
{
DateTimeOffset? oldValue = _ReleaseDate;
SetReleaseDate(oldValue, ref value);
if (oldValue != value)
{
_ReleaseDate = value;
}
}
}
/// <summary>
/// Backing field for DateAdded
/// </summary>
protected DateTime _DateAdded;
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before setting.
/// </summary>
partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before returning.
/// </summary>
partial void GetDateAdded(ref DateTime result);
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateAdded
{
get
{
DateTime value = _DateAdded;
GetDateAdded(ref value);
return (_DateAdded = value);
}
internal set
{
DateTime oldValue = _DateAdded;
SetDateAdded(oldValue, ref value);
if (oldValue != value)
{
_DateAdded = value;
}
}
}
/// <summary>
/// Backing field for DateModified
/// </summary>
protected DateTime _DateModified;
/// <summary>
/// When provided in a partial class, allows value of DateModified to be changed before setting.
/// </summary>
partial void SetDateModified(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateModified to be changed before returning.
/// </summary>
partial void GetDateModified(ref DateTime result);
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateModified
{
get
{
DateTime value = _DateModified;
GetDateModified(ref value);
return (_DateModified = value);
}
internal set
{
DateTime oldValue = _DateModified;
SetDateModified(oldValue, ref value);
if (oldValue != value)
{
_DateModified = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.PersonRole> PersonRoles { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Genre> Genres { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Artwork> Artwork { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Rating> Ratings { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; }
}
}

@ -0,0 +1,158 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MetadataProvider
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MetadataProvider()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MetadataProvider CreateMetadataProviderUnsafe()
{
return new MetadataProvider();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
public MetadataProvider(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
public static MetadataProvider Create(string name)
{
return new MetadataProvider(name);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Required, Max length = 1024
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

@ -0,0 +1,189 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MetadataProviderId
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MetadataProviderId()
{
// NOTE: This class has one-to-one associations with MetadataProviderId.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MetadataProviderId CreateMetadataProviderIdUnsafe()
{
return new MetadataProviderId();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="providerid"></param>
/// <param name="_metadata0"></param>
/// <param name="_person1"></param>
/// <param name="_personrole2"></param>
/// <param name="_ratingsource3"></param>
public MetadataProviderId(string providerid, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.Person _person1, global::Jellyfin.Data.Entities.PersonRole _personrole2, global::Jellyfin.Data.Entities.RatingSource _ratingsource3)
{
// NOTE: This class has one-to-one associations with MetadataProviderId.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
if (string.IsNullOrEmpty(providerid)) throw new ArgumentNullException(nameof(providerid));
this.ProviderId = providerid;
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.Sources.Add(this);
if (_person1 == null) throw new ArgumentNullException(nameof(_person1));
_person1.Sources.Add(this);
if (_personrole2 == null) throw new ArgumentNullException(nameof(_personrole2));
_personrole2.Sources.Add(this);
if (_ratingsource3 == null) throw new ArgumentNullException(nameof(_ratingsource3));
_ratingsource3.Source = this;
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="providerid"></param>
/// <param name="_metadata0"></param>
/// <param name="_person1"></param>
/// <param name="_personrole2"></param>
/// <param name="_ratingsource3"></param>
public static MetadataProviderId Create(string providerid, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.Person _person1, global::Jellyfin.Data.Entities.PersonRole _personrole2, global::Jellyfin.Data.Entities.RatingSource _ratingsource3)
{
return new MetadataProviderId(providerid, _metadata0, _person1, _personrole2, _ratingsource3);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for ProviderId
/// </summary>
protected string _ProviderId;
/// <summary>
/// When provided in a partial class, allows value of ProviderId to be changed before setting.
/// </summary>
partial void SetProviderId(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of ProviderId to be changed before returning.
/// </summary>
partial void GetProviderId(ref string result);
/// <summary>
/// Required, Max length = 255
/// </summary>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string ProviderId
{
get
{
string value = _ProviderId;
GetProviderId(ref value);
return (_ProviderId = value);
}
set
{
string oldValue = _ProviderId;
SetProviderId(oldValue, ref value);
if (oldValue != value)
{
_ProviderId = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
public virtual global::Jellyfin.Data.Entities.MetadataProvider MetadataProvider { get; set; }
}
}

@ -0,0 +1,84 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Movie: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Movie(): base()
{
Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
MovieMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MovieMetadata>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Movie CreateMovieUnsafe()
{
return new Movie();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public Movie(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
this.MovieMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MovieMetadata>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static Movie Create(Guid urlid, DateTime dateadded)
{
return new Movie(urlid, dateadded);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.MovieMetadata> MovieMetadata { get; protected set; }
}
}

@ -0,0 +1,239 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MovieMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MovieMetadata(): base()
{
Studios = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MovieMetadata CreateMovieMetadataUnsafe()
{
return new MovieMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_movie0"></param>
public MovieMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Movie _movie0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0));
_movie0.MovieMetadata.Add(this);
this.Studios = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_movie0"></param>
public static MovieMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Movie _movie0)
{
return new MovieMetadata(title, language, dateadded, datemodified, _movie0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Outline
/// </summary>
protected string _Outline;
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before setting.
/// </summary>
partial void SetOutline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before returning.
/// </summary>
partial void GetOutline(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Outline
{
get
{
string value = _Outline;
GetOutline(ref value);
return (_Outline = value);
}
set
{
string oldValue = _Outline;
SetOutline(oldValue, ref value);
if (oldValue != value)
{
_Outline = value;
}
}
}
/// <summary>
/// Backing field for Plot
/// </summary>
protected string _Plot;
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before setting.
/// </summary>
partial void SetPlot(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before returning.
/// </summary>
partial void GetPlot(ref string result);
/// <summary>
/// Max length = 65535
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string Plot
{
get
{
string value = _Plot;
GetPlot(ref value);
return (_Plot = value);
}
set
{
string oldValue = _Plot;
SetPlot(oldValue, ref value);
if (oldValue != value)
{
_Plot = value;
}
}
}
/// <summary>
/// Backing field for Tagline
/// </summary>
protected string _Tagline;
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before setting.
/// </summary>
partial void SetTagline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before returning.
/// </summary>
partial void GetTagline(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Tagline
{
get
{
string value = _Tagline;
GetTagline(ref value);
return (_Tagline = value);
}
set
{
string oldValue = _Tagline;
SetTagline(oldValue, ref value);
if (oldValue != value)
{
_Tagline = value;
}
}
}
/// <summary>
/// Backing field for Country
/// </summary>
protected string _Country;
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before setting.
/// </summary>
partial void SetCountry(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before returning.
/// </summary>
partial void GetCountry(ref string result);
/// <summary>
/// Max length = 2
/// </summary>
[MaxLength(2)]
[StringLength(2)]
public string Country
{
get
{
string value = _Country;
GetCountry(ref value);
return (_Country = value);
}
set
{
string oldValue = _Country;
SetCountry(oldValue, ref value);
if (oldValue != value)
{
_Country = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.Company> Studios { get; protected set; }
}
}

@ -0,0 +1,84 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MusicAlbum: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MusicAlbum(): base()
{
MusicAlbumMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata>();
Tracks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Track>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MusicAlbum CreateMusicAlbumUnsafe()
{
return new MusicAlbum();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public MusicAlbum(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
this.MusicAlbumMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata>();
this.Tracks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Track>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static MusicAlbum Create(Guid urlid, DateTime dateadded)
{
return new MusicAlbum(urlid, dateadded);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.MusicAlbumMetadata> MusicAlbumMetadata { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Track> Tracks { get; protected set; }
}
}

@ -0,0 +1,202 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MusicAlbumMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MusicAlbumMetadata(): base()
{
Labels = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MusicAlbumMetadata CreateMusicAlbumMetadataUnsafe()
{
return new MusicAlbumMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_musicalbum0"></param>
public MusicAlbumMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0));
_musicalbum0.MusicAlbumMetadata.Add(this);
this.Labels = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_musicalbum0"></param>
public static MusicAlbumMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0)
{
return new MusicAlbumMetadata(title, language, dateadded, datemodified, _musicalbum0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Barcode
/// </summary>
protected string _Barcode;
/// <summary>
/// When provided in a partial class, allows value of Barcode to be changed before setting.
/// </summary>
partial void SetBarcode(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Barcode to be changed before returning.
/// </summary>
partial void GetBarcode(ref string result);
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string Barcode
{
get
{
string value = _Barcode;
GetBarcode(ref value);
return (_Barcode = value);
}
set
{
string oldValue = _Barcode;
SetBarcode(oldValue, ref value);
if (oldValue != value)
{
_Barcode = value;
}
}
}
/// <summary>
/// Backing field for LabelNumber
/// </summary>
protected string _LabelNumber;
/// <summary>
/// When provided in a partial class, allows value of LabelNumber to be changed before setting.
/// </summary>
partial void SetLabelNumber(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of LabelNumber to be changed before returning.
/// </summary>
partial void GetLabelNumber(ref string result);
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string LabelNumber
{
get
{
string value = _LabelNumber;
GetLabelNumber(ref value);
return (_LabelNumber = value);
}
set
{
string oldValue = _LabelNumber;
SetLabelNumber(oldValue, ref value);
if (oldValue != value)
{
_LabelNumber = value;
}
}
}
/// <summary>
/// Backing field for Country
/// </summary>
protected string _Country;
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before setting.
/// </summary>
partial void SetCountry(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before returning.
/// </summary>
partial void GetCountry(ref string result);
/// <summary>
/// Max length = 2
/// </summary>
[MaxLength(2)]
[StringLength(2)]
public string Country
{
get
{
string value = _Country;
GetCountry(ref value);
return (_Country = value);
}
set
{
string oldValue = _Country;
SetCountry(oldValue, ref value);
if (oldValue != value)
{
_Country = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.Company> Labels { get; protected set; }
}
}

@ -0,0 +1,152 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Permission
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Permission()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Permission CreatePermissionUnsafe()
{
return new Permission();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="kind"></param>
/// <param name="value"></param>
/// <param name="_user0"></param>
/// <param name="_group1"></param>
public Permission(global::Jellyfin.Data.Enums.PermissionKind kind, bool value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
{
this.Kind = kind;
this.Value = value;
if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
_user0.Permissions.Add(this);
if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
_group1.GroupPermissions.Add(this);
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="kind"></param>
/// <param name="value"></param>
/// <param name="_user0"></param>
/// <param name="_group1"></param>
public static Permission Create(global::Jellyfin.Data.Enums.PermissionKind kind, bool value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
{
return new Permission(kind, value, _user0, _group1);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id { get; protected set; }
/// <summary>
/// Backing field for Kind
/// </summary>
protected global::Jellyfin.Data.Enums.PermissionKind _Kind;
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before setting.
/// </summary>
partial void SetKind(global::Jellyfin.Data.Enums.PermissionKind oldValue, ref global::Jellyfin.Data.Enums.PermissionKind newValue);
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before returning.
/// </summary>
partial void GetKind(ref global::Jellyfin.Data.Enums.PermissionKind result);
/// <summary>
/// Required
/// </summary>
[Required]
public global::Jellyfin.Data.Enums.PermissionKind Kind
{
get
{
global::Jellyfin.Data.Enums.PermissionKind value = _Kind;
GetKind(ref value);
return (_Kind = value);
}
set
{
global::Jellyfin.Data.Enums.PermissionKind oldValue = _Kind;
SetKind(oldValue, ref value);
if (oldValue != value)
{
_Kind = value;
OnPropertyChanged();
}
}
}
/// <summary>
/// Required
/// </summary>
[Required]
public bool Value { get; set; }
/// <summary>
/// Concurrency token
/// </summary>
[Timestamp]
public Byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

@ -0,0 +1,40 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
namespace Jellyfin.Data.Enums
{
public enum PermissionKind : Int32
{
IsAdministrator,
IsHidden,
IsDisabled,
BlockUnrateditems,
EnbleSharedDeviceControl,
EnableRemoteAccess,
EnableLiveTvManagement,
EnableLiveTvAccess,
EnableMediaPlayback,
EnableAudioPlaybackTranscoding,
EnableVideoPlaybackTranscoding,
EnableContentDeletion,
EnableContentDownloading,
EnableSyncTranscoding,
EnableMediaConversion,
EnableAllDevices,
EnableAllChannels,
EnableAllFolders,
EnablePublicSharing,
AccessSchedules
}
}

@ -0,0 +1,312 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Person
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Person()
{
Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Person CreatePersonUnsafe()
{
return new Person();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid"></param>
/// <param name="name"></param>
public Person(Guid urlid, string name, DateTime dateadded, DateTime datemodified)
{
this.UrlId = urlid;
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid"></param>
/// <param name="name"></param>
public static Person Create(Guid urlid, string name, DateTime dateadded, DateTime datemodified)
{
return new Person(urlid, name, dateadded, datemodified);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for UrlId
/// </summary>
protected Guid _UrlId;
/// <summary>
/// When provided in a partial class, allows value of UrlId to be changed before setting.
/// </summary>
partial void SetUrlId(Guid oldValue, ref Guid newValue);
/// <summary>
/// When provided in a partial class, allows value of UrlId to be changed before returning.
/// </summary>
partial void GetUrlId(ref Guid result);
/// <summary>
/// Required
/// </summary>
[Required]
public Guid UrlId
{
get
{
Guid value = _UrlId;
GetUrlId(ref value);
return (_UrlId = value);
}
set
{
Guid oldValue = _UrlId;
SetUrlId(oldValue, ref value);
if (oldValue != value)
{
_UrlId = value;
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Required, Max length = 1024
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
/// <summary>
/// Backing field for SourceId
/// </summary>
protected string _SourceId;
/// <summary>
/// When provided in a partial class, allows value of SourceId to be changed before setting.
/// </summary>
partial void SetSourceId(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of SourceId to be changed before returning.
/// </summary>
partial void GetSourceId(ref string result);
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string SourceId
{
get
{
string value = _SourceId;
GetSourceId(ref value);
return (_SourceId = value);
}
set
{
string oldValue = _SourceId;
SetSourceId(oldValue, ref value);
if (oldValue != value)
{
_SourceId = value;
}
}
}
/// <summary>
/// Backing field for DateAdded
/// </summary>
protected DateTime _DateAdded;
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before setting.
/// </summary>
partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before returning.
/// </summary>
partial void GetDateAdded(ref DateTime result);
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateAdded
{
get
{
DateTime value = _DateAdded;
GetDateAdded(ref value);
return (_DateAdded = value);
}
internal set
{
DateTime oldValue = _DateAdded;
SetDateAdded(oldValue, ref value);
if (oldValue != value)
{
_DateAdded = value;
}
}
}
/// <summary>
/// Backing field for DateModified
/// </summary>
protected DateTime _DateModified;
/// <summary>
/// When provided in a partial class, allows value of DateModified to be changed before setting.
/// </summary>
partial void SetDateModified(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateModified to be changed before returning.
/// </summary>
partial void GetDateModified(ref DateTime result);
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateModified
{
get
{
DateTime value = _DateModified;
GetDateModified(ref value);
return (_DateModified = value);
}
internal set
{
DateTime oldValue = _DateModified;
SetDateModified(oldValue, ref value);
if (oldValue != value)
{
_DateModified = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; }
}
}

@ -0,0 +1,215 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class PersonRole
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected PersonRole()
{
// NOTE: This class has one-to-one associations with PersonRole.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static PersonRole CreatePersonRoleUnsafe()
{
return new PersonRole();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="type"></param>
/// <param name="_metadata0"></param>
public PersonRole(global::Jellyfin.Data.Enums.PersonRoleType type, global::Jellyfin.Data.Entities.Metadata _metadata0)
{
// NOTE: This class has one-to-one associations with PersonRole.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
this.Type = type;
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.PersonRoles.Add(this);
this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="type"></param>
/// <param name="_metadata0"></param>
public static PersonRole Create(global::Jellyfin.Data.Enums.PersonRoleType type, global::Jellyfin.Data.Entities.Metadata _metadata0)
{
return new PersonRole(type, _metadata0);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Backing field for Role
/// </summary>
protected string _Role;
/// <summary>
/// When provided in a partial class, allows value of Role to be changed before setting.
/// </summary>
partial void SetRole(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Role to be changed before returning.
/// </summary>
partial void GetRole(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Role
{
get
{
string value = _Role;
GetRole(ref value);
return (_Role = value);
}
set
{
string oldValue = _Role;
SetRole(oldValue, ref value);
if (oldValue != value)
{
_Role = value;
}
}
}
/// <summary>
/// Backing field for Type
/// </summary>
protected global::Jellyfin.Data.Enums.PersonRoleType _Type;
/// <summary>
/// When provided in a partial class, allows value of Type to be changed before setting.
/// </summary>
partial void SetType(global::Jellyfin.Data.Enums.PersonRoleType oldValue, ref global::Jellyfin.Data.Enums.PersonRoleType newValue);
/// <summary>
/// When provided in a partial class, allows value of Type to be changed before returning.
/// </summary>
partial void GetType(ref global::Jellyfin.Data.Enums.PersonRoleType result);
/// <summary>
/// Required
/// </summary>
[Required]
public global::Jellyfin.Data.Enums.PersonRoleType Type
{
get
{
global::Jellyfin.Data.Enums.PersonRoleType value = _Type;
GetType(ref value);
return (_Type = value);
}
set
{
global::Jellyfin.Data.Enums.PersonRoleType oldValue = _Type;
SetType(oldValue, ref value);
if (oldValue != value)
{
_Type = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
public virtual global::Jellyfin.Data.Entities.Person Person { get; set; }
public virtual global::Jellyfin.Data.Entities.Artwork Artwork { get; set; }
public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; }
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save