repo creation with initial code after cloning public repo

This commit is contained in:
2026-02-19 07:36:25 -05:00
commit 460884fea3
2860 changed files with 650825 additions and 0 deletions
@@ -0,0 +1,11 @@
using System;
namespace Jellyfin.Data.Attributes;
/// <summary>
/// Attribute to specify that the enum value is to be ignored when generating the openapi spec.
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public sealed class OpenApiIgnoreEnumAttribute : Attribute
{
}
+32
View File
@@ -0,0 +1,32 @@
#pragma warning disable CS1591
using System;
using Jellyfin.Database.Implementations.Enums;
namespace Jellyfin.Data
{
public static class DayOfWeekHelper
{
public static DayOfWeek[] GetDaysOfWeek(DynamicDayOfWeek day)
{
return day switch
{
DynamicDayOfWeek.Everyday => new[] { DayOfWeek.Sunday, DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday },
DynamicDayOfWeek.Weekday => new[] { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday },
DynamicDayOfWeek.Weekend => new[] { DayOfWeek.Sunday, DayOfWeek.Saturday },
_ => new[] { (DayOfWeek)day }
};
}
public static bool Contains(this DynamicDayOfWeek dynamicDayOfWeek, DayOfWeek dayOfWeek)
{
return dynamicDayOfWeek switch
{
DynamicDayOfWeek.Everyday => true,
DynamicDayOfWeek.Weekday => dayOfWeek is >= DayOfWeek.Monday and <= DayOfWeek.Friday,
DynamicDayOfWeek.Weekend => dayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday,
_ => (DayOfWeek)dynamicDayOfWeek == dayOfWeek
};
}
}
}
+22
View File
@@ -0,0 +1,22 @@
namespace Jellyfin.Data.Dtos;
/// <summary>
/// A dto representing custom options for a device.
/// </summary>
public class DeviceOptionsDto
{
/// <summary>
/// Gets or sets the id.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Gets or sets the device id.
/// </summary>
public string? DeviceId { get; set; }
/// <summary>
/// Gets or sets the custom name.
/// </summary>
public string? CustomName { get; set; }
}
+49
View File
@@ -0,0 +1,49 @@
namespace Jellyfin.Data.Enums;
/// <summary>
/// Activity log sorting options.
/// </summary>
public enum ActivityLogSortBy
{
/// <summary>
/// Sort by name.
/// </summary>
Name = 0,
/// <summary>
/// Sort by overview.
/// </summary>
Overiew = 1,
/// <summary>
/// Sort by short overview.
/// </summary>
ShortOverview = 2,
/// <summary>
/// Sort by type.
/// </summary>
Type = 3,
/*
/// <summary>
/// Sort by item name.
/// </summary>
Item = 4,
*/
/// <summary>
/// Sort by date.
/// </summary>
DateCreated = 5,
/// <summary>
/// Sort by username.
/// </summary>
Username = 6,
/// <summary>
/// Sort by severity.
/// </summary>
LogSeverity = 7
}
+22
View File
@@ -0,0 +1,22 @@
namespace Jellyfin.Data.Enums;
/// <summary>
/// An enum representing formats of spatial audio.
/// </summary>
public enum AudioSpatialFormat
{
/// <summary>
/// None audio spatial format.
/// </summary>
None,
/// <summary>
/// Dolby Atmos audio spatial format.
/// </summary>
DolbyAtmos,
/// <summary>
/// DTS:X audio spatial format.
/// </summary>
DTSX,
}
+205
View File
@@ -0,0 +1,205 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// The base item kind.
/// </summary>
/// <remarks>
/// This enum is generated from all classes that inherit from <c>BaseItem</c>.
/// </remarks>
public enum BaseItemKind
{
/// <summary>
/// Item is aggregate folder.
/// </summary>
AggregateFolder,
/// <summary>
/// Item is audio.
/// </summary>
Audio,
/// <summary>
/// Item is audio book.
/// </summary>
AudioBook,
/// <summary>
/// Item is base plugin folder.
/// </summary>
BasePluginFolder,
/// <summary>
/// Item is book.
/// </summary>
Book,
/// <summary>
/// Item is box set.
/// </summary>
BoxSet,
/// <summary>
/// Item is channel.
/// </summary>
Channel,
/// <summary>
/// Item is channel folder item.
/// </summary>
ChannelFolderItem,
/// <summary>
/// Item is collection folder.
/// </summary>
CollectionFolder,
/// <summary>
/// Item is episode.
/// </summary>
Episode,
/// <summary>
/// Item is folder.
/// </summary>
Folder,
/// <summary>
/// Item is genre.
/// </summary>
Genre,
/// <summary>
/// Item is manual playlists folder.
/// </summary>
ManualPlaylistsFolder,
/// <summary>
/// Item is movie.
/// </summary>
Movie,
/// <summary>
/// Item is a live tv channel.
/// </summary>
LiveTvChannel,
/// <summary>
/// Item is a live tv program.
/// </summary>
LiveTvProgram,
/// <summary>
/// Item is music album.
/// </summary>
MusicAlbum,
/// <summary>
/// Item is music artist.
/// </summary>
MusicArtist,
/// <summary>
/// Item is music genre.
/// </summary>
MusicGenre,
/// <summary>
/// Item is music video.
/// </summary>
MusicVideo,
/// <summary>
/// Item is person.
/// </summary>
Person,
/// <summary>
/// Item is photo.
/// </summary>
Photo,
/// <summary>
/// Item is photo album.
/// </summary>
PhotoAlbum,
/// <summary>
/// Item is playlist.
/// </summary>
Playlist,
/// <summary>
/// Item is playlist folder.
/// </summary>
PlaylistsFolder,
/// <summary>
/// Item is program.
/// </summary>
Program,
/// <summary>
/// Item is recording.
/// </summary>
/// <remarks>
/// Manually added.
/// </remarks>
Recording,
/// <summary>
/// Item is season.
/// </summary>
Season,
/// <summary>
/// Item is series.
/// </summary>
Series,
/// <summary>
/// Item is studio.
/// </summary>
Studio,
/// <summary>
/// Item is trailer.
/// </summary>
Trailer,
/// <summary>
/// Item is live tv channel.
/// </summary>
/// <remarks>
/// Type is overridden.
/// </remarks>
TvChannel,
/// <summary>
/// Item is live tv program.
/// </summary>
/// <remarks>
/// Type is overridden.
/// </remarks>
TvProgram,
/// <summary>
/// Item is user root folder.
/// </summary>
UserRootFolder,
/// <summary>
/// Item is user view.
/// </summary>
UserView,
/// <summary>
/// Item is video.
/// </summary>
Video,
/// <summary>
/// Item is year.
/// </summary>
Year
}
}
+165
View File
@@ -0,0 +1,165 @@
#pragma warning disable SA1300 // The name of a C# element does not begin with an upper-case letter. - disabled due to legacy requirement.
using Jellyfin.Data.Attributes;
namespace Jellyfin.Data.Enums;
/// <summary>
/// Collection type.
/// </summary>
public enum CollectionType
{
/// <summary>
/// Unknown collection.
/// </summary>
unknown = 0,
/// <summary>
/// Movies collection.
/// </summary>
movies = 1,
/// <summary>
/// Tv shows collection.
/// </summary>
tvshows = 2,
/// <summary>
/// Music collection.
/// </summary>
music = 3,
/// <summary>
/// Music videos collection.
/// </summary>
musicvideos = 4,
/// <summary>
/// Trailers collection.
/// </summary>
trailers = 5,
/// <summary>
/// Home videos collection.
/// </summary>
homevideos = 6,
/// <summary>
/// Box sets collection.
/// </summary>
boxsets = 7,
/// <summary>
/// Books collection.
/// </summary>
books = 8,
/// <summary>
/// Photos collection.
/// </summary>
photos = 9,
/// <summary>
/// Live tv collection.
/// </summary>
livetv = 10,
/// <summary>
/// Playlists collection.
/// </summary>
playlists = 11,
/// <summary>
/// Folders collection.
/// </summary>
folders = 12,
/// <summary>
/// Tv show series collection.
/// </summary>
[OpenApiIgnoreEnum]
tvshowseries = 101,
/// <summary>
/// Tv genres collection.
/// </summary>
[OpenApiIgnoreEnum]
tvgenres = 102,
/// <summary>
/// Tv genre collection.
/// </summary>
[OpenApiIgnoreEnum]
tvgenre = 103,
/// <summary>
/// Tv latest collection.
/// </summary>
[OpenApiIgnoreEnum]
tvlatest = 104,
/// <summary>
/// Tv next up collection.
/// </summary>
[OpenApiIgnoreEnum]
tvnextup = 105,
/// <summary>
/// Tv resume collection.
/// </summary>
[OpenApiIgnoreEnum]
tvresume = 106,
/// <summary>
/// Tv favorite series collection.
/// </summary>
[OpenApiIgnoreEnum]
tvfavoriteseries = 107,
/// <summary>
/// Tv favorite episodes collection.
/// </summary>
[OpenApiIgnoreEnum]
tvfavoriteepisodes = 108,
/// <summary>
/// Latest movies collection.
/// </summary>
[OpenApiIgnoreEnum]
movielatest = 109,
/// <summary>
/// Movies to resume collection.
/// </summary>
[OpenApiIgnoreEnum]
movieresume = 110,
/// <summary>
/// Movie movie collection.
/// </summary>
[OpenApiIgnoreEnum]
moviemovies = 111,
/// <summary>
/// Movie collections collection.
/// </summary>
[OpenApiIgnoreEnum]
moviecollection = 112,
/// <summary>
/// Movie favorites collection.
/// </summary>
[OpenApiIgnoreEnum]
moviefavorites = 113,
/// <summary>
/// Movie genres collection.
/// </summary>
[OpenApiIgnoreEnum]
moviegenres = 114,
/// <summary>
/// Movie genre collection.
/// </summary>
[OpenApiIgnoreEnum]
moviegenre = 115
}
+157
View File
@@ -0,0 +1,157 @@
namespace Jellyfin.Data.Enums;
/// <summary>
/// These represent sort orders.
/// </summary>
public enum ItemSortBy
{
/// <summary>
/// Default sort order.
/// </summary>
Default = 0,
/// <summary>
/// The aired episode order.
/// </summary>
AiredEpisodeOrder = 1,
/// <summary>
/// The album.
/// </summary>
Album = 2,
/// <summary>
/// The album artist.
/// </summary>
AlbumArtist = 3,
/// <summary>
/// The artist.
/// </summary>
Artist = 4,
/// <summary>
/// The date created.
/// </summary>
DateCreated = 5,
/// <summary>
/// The official rating.
/// </summary>
OfficialRating = 6,
/// <summary>
/// The date played.
/// </summary>
DatePlayed = 7,
/// <summary>
/// The premiere date.
/// </summary>
PremiereDate = 8,
/// <summary>
/// The start date.
/// </summary>
StartDate = 9,
/// <summary>
/// The sort name.
/// </summary>
SortName = 10,
/// <summary>
/// The name.
/// </summary>
Name = 11,
/// <summary>
/// The random.
/// </summary>
Random = 12,
/// <summary>
/// The runtime.
/// </summary>
Runtime = 13,
/// <summary>
/// The community rating.
/// </summary>
CommunityRating = 14,
/// <summary>
/// The production year.
/// </summary>
ProductionYear = 15,
/// <summary>
/// The play count.
/// </summary>
PlayCount = 16,
/// <summary>
/// The critic rating.
/// </summary>
CriticRating = 17,
/// <summary>
/// The IsFolder boolean.
/// </summary>
IsFolder = 18,
/// <summary>
/// The IsUnplayed boolean.
/// </summary>
IsUnplayed = 19,
/// <summary>
/// The IsPlayed boolean.
/// </summary>
IsPlayed = 20,
/// <summary>
/// The series sort.
/// </summary>
SeriesSortName = 21,
/// <summary>
/// The video bitrate.
/// </summary>
VideoBitRate = 22,
/// <summary>
/// The air time.
/// </summary>
AirTime = 23,
/// <summary>
/// The studio.
/// </summary>
Studio = 24,
/// <summary>
/// The IsFavouriteOrLiked boolean.
/// </summary>
IsFavoriteOrLiked = 25,
/// <summary>
/// The last content added date.
/// </summary>
DateLastContentAdded = 26,
/// <summary>
/// The series last played date.
/// </summary>
SeriesDatePlayed = 27,
/// <summary>
/// The parent index number.
/// </summary>
ParentIndexNumber = 28,
/// <summary>
/// The index number.
/// </summary>
IndexNumber = 29,
}
@@ -0,0 +1,22 @@
#pragma warning disable SA1300 // Lowercase required for backwards compat.
using System.ComponentModel;
namespace Jellyfin.Data.Enums;
/// <summary>
/// Media streaming protocol.
/// Lowercase for backwards compatibility.
/// </summary>
[DefaultValue(http)]
public enum MediaStreamProtocol
{
/// <summary>
/// HTTP.
/// </summary>
http = 0,
/// <summary>
/// HTTP Live Streaming.
/// </summary>
hls = 1
}
+32
View File
@@ -0,0 +1,32 @@
namespace Jellyfin.Data.Enums;
/// <summary>
/// Media types.
/// </summary>
public enum MediaType
{
/// <summary>
/// Unknown media type.
/// </summary>
Unknown = 0,
/// <summary>
/// Video media.
/// </summary>
Video = 1,
/// <summary>
/// Audio media.
/// </summary>
Audio = 2,
/// <summary>
/// Photo media.
/// </summary>
Photo = 3,
/// <summary>
/// Book media.
/// </summary>
Book = 4
}
+133
View File
@@ -0,0 +1,133 @@
namespace Jellyfin.Data.Enums;
/// <summary>
/// The person kind.
/// </summary>
public enum PersonKind
{
/// <summary>
/// An unknown person kind.
/// </summary>
Unknown,
/// <summary>
/// A person whose profession is acting on the stage, in films, or on television.
/// </summary>
Actor,
/// <summary>
/// A person who supervises the actors and other staff in a film, play, or similar production.
/// </summary>
Director,
/// <summary>
/// A person who writes music, especially as a professional occupation.
/// </summary>
Composer,
/// <summary>
/// A writer of a book, article, or document. Can also be used as a generic term for music writer if there is a lack of specificity.
/// </summary>
Writer,
/// <summary>
/// A well-known actor or other performer who appears in a work in which they do not have a regular role.
/// </summary>
GuestStar,
/// <summary>
/// A person responsible for the financial and managerial aspects of the making of a film or broadcast or for staging a play, opera, etc.
/// </summary>
Producer,
/// <summary>
/// A person who directs the performance of an orchestra or choir.
/// </summary>
Conductor,
/// <summary>
/// A person who writes the words to a song or musical.
/// </summary>
Lyricist,
/// <summary>
/// A person who adapts a musical composition for performance.
/// </summary>
Arranger,
/// <summary>
/// An audio engineer who performed a general engineering role.
/// </summary>
Engineer,
/// <summary>
/// An engineer responsible for using a mixing console to mix a recorded track into a single piece of music suitable for release.
/// </summary>
Mixer,
/// <summary>
/// A person who remixed a recording by taking one or more other tracks, substantially altering them and mixing them together with other material.
/// </summary>
Remixer,
/// <summary>
/// A person who created the material.
/// </summary>
Creator,
/// <summary>
/// A person who was the artist.
/// </summary>
Artist,
/// <summary>
/// A person who was the album artist.
/// </summary>
AlbumArtist,
/// <summary>
/// A person who was the author.
/// </summary>
Author,
/// <summary>
/// A person who was the illustrator.
/// </summary>
Illustrator,
/// <summary>
/// A person responsible for drawing the art.
/// </summary>
Penciller,
/// <summary>
/// A person responsible for inking the pencil art.
/// </summary>
Inker,
/// <summary>
/// A person responsible for applying color to drawings.
/// </summary>
Colorist,
/// <summary>
/// A person responsible for drawing text and speech bubbles.
/// </summary>
Letterer,
/// <summary>
/// A person responsible for drawing the cover art.
/// </summary>
CoverArtist,
/// <summary>
/// A person contributing to a resource by revising or elucidating the content, e.g., adding an introduction, notes, or other critical matter.
/// An editor may also prepare a resource for production, publication, or distribution.
/// </summary>
Editor,
/// <summary>
/// A person who renders a text from one language into another.
/// </summary>
Translator
}
@@ -0,0 +1,28 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// Enum SyncPlayAccessRequirementType.
/// </summary>
public enum SyncPlayAccessRequirementType
{
/// <summary>
/// User must have access to SyncPlay, in some form.
/// </summary>
HasAccess = 0,
/// <summary>
/// User must be able to create groups.
/// </summary>
CreateGroup = 1,
/// <summary>
/// User must be able to join groups.
/// </summary>
JoinGroup = 2,
/// <summary>
/// User must be in a group.
/// </summary>
IsInGroup = 3
}
}
+53
View File
@@ -0,0 +1,53 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// An enum representing an unrated item.
/// </summary>
public enum UnratedItem
{
/// <summary>
/// A movie.
/// </summary>
Movie = 0,
/// <summary>
/// A trailer.
/// </summary>
Trailer = 1,
/// <summary>
/// A series.
/// </summary>
Series = 2,
/// <summary>
/// Music.
/// </summary>
Music = 3,
/// <summary>
/// A book.
/// </summary>
Book = 4,
/// <summary>
/// A live TV channel.
/// </summary>
LiveTvChannel = 5,
/// <summary>
/// A live TV program.
/// </summary>
LiveTvProgram = 6,
/// <summary>
/// Channel content.
/// </summary>
ChannelContent = 7,
/// <summary>
/// Another type, not covered by the other fields.
/// </summary>
Other = 8
}
}
+22
View File
@@ -0,0 +1,22 @@
namespace Jellyfin.Data.Enums;
/// <summary>
/// An enum representing video ranges.
/// </summary>
public enum VideoRange
{
/// <summary>
/// Unknown video range.
/// </summary>
Unknown,
/// <summary>
/// SDR video range.
/// </summary>
SDR,
/// <summary>
/// HDR video range.
/// </summary>
HDR
}
+73
View File
@@ -0,0 +1,73 @@
namespace Jellyfin.Data.Enums;
/// <summary>
/// An enum representing types of video ranges.
/// </summary>
public enum VideoRangeType
{
/// <summary>
/// Unknown video range type.
/// </summary>
Unknown,
/// <summary>
/// SDR video range type (8bit).
/// </summary>
SDR,
/// <summary>
/// HDR10 video range type (10bit).
/// </summary>
HDR10,
/// <summary>
/// HLG video range type (10bit).
/// </summary>
HLG,
/// <summary>
/// Dolby Vision video range type (10bit encoded / 12bit remapped).
/// </summary>
DOVI,
/// <summary>
/// Dolby Vision with HDR10 video range fallback (10bit).
/// </summary>
DOVIWithHDR10,
/// <summary>
/// Dolby Vision with HLG video range fallback (10bit).
/// </summary>
DOVIWithHLG,
/// <summary>
/// Dolby Vision with SDR video range fallback (8bit / 10bit).
/// </summary>
DOVIWithSDR,
/// <summary>
/// Dolby Vision with Enhancment Layer (Profile 7).
/// </summary>
DOVIWithEL,
/// <summary>
/// Dolby Vision and HDR10+ Metadata coexists.
/// </summary>
DOVIWithHDR10Plus,
/// <summary>
/// Dolby Vision with Enhancment Layer (Profile 7) and HDR10+ Metadata coexists.
/// </summary>
DOVIWithELHDR10Plus,
/// <summary>
/// Dolby Vision with invalid configuration. e.g. Profile 8 compat id 6.
/// When using this range, the server would assume the video is still HDR10 after removing the Dolby Vision metadata.
/// </summary>
DOVIInvalid,
/// <summary>
/// HDR10+ video range type (10bit to 16bit).
/// </summary>
HDR10Plus
}
+26
View File
@@ -0,0 +1,26 @@
using System;
namespace Jellyfin.Data.Events
{
/// <summary>
/// Provides a generic EventArgs subclass that can hold any kind of object.
/// </summary>
/// <typeparam name="T">The type of this event.</typeparam>
public class GenericEventArgs<T> : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="GenericEventArgs{T}"/> class.
/// </summary>
/// <param name="arg">The argument.</param>
public GenericEventArgs(T arg)
{
Argument = arg;
}
/// <summary>
/// Gets the argument.
/// </summary>
/// <value>The argument.</value>
public T Argument { get; }
}
}
@@ -0,0 +1,11 @@
using System;
namespace Jellyfin.Data.Events.System
{
/// <summary>
/// An event that occurs when there is a pending restart.
/// </summary>
public class PendingRestartEventArgs : EventArgs
{
}
}
@@ -0,0 +1,18 @@
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{
/// <summary>
/// An event that occurs when a user is created.
/// </summary>
public class UserCreatedEventArgs : GenericEventArgs<User>
{
/// <summary>
/// Initializes a new instance of the <see cref="UserCreatedEventArgs"/> class.
/// </summary>
/// <param name="arg">The user.</param>
public UserCreatedEventArgs(User arg) : base(arg)
{
}
}
}
@@ -0,0 +1,18 @@
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{
/// <summary>
/// An event that occurs when a user is deleted.
/// </summary>
public class UserDeletedEventArgs : GenericEventArgs<User>
{
/// <summary>
/// Initializes a new instance of the <see cref="UserDeletedEventArgs"/> class.
/// </summary>
/// <param name="arg">The user.</param>
public UserDeletedEventArgs(User arg) : base(arg)
{
}
}
}
@@ -0,0 +1,18 @@
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{
/// <summary>
/// An event that occurs when a user is locked out.
/// </summary>
public class UserLockedOutEventArgs : GenericEventArgs<User>
{
/// <summary>
/// Initializes a new instance of the <see cref="UserLockedOutEventArgs"/> class.
/// </summary>
/// <param name="arg">The user.</param>
public UserLockedOutEventArgs(User arg) : base(arg)
{
}
}
}
@@ -0,0 +1,18 @@
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{
/// <summary>
/// An event that occurs when a user's password has changed.
/// </summary>
public class UserPasswordChangedEventArgs : GenericEventArgs<User>
{
/// <summary>
/// Initializes a new instance of the <see cref="UserPasswordChangedEventArgs"/> class.
/// </summary>
/// <param name="arg">The user.</param>
public UserPasswordChangedEventArgs(User arg) : base(arg)
{
}
}
}
@@ -0,0 +1,18 @@
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{
/// <summary>
/// An event that occurs when a user is updated.
/// </summary>
public class UserUpdatedEventArgs : GenericEventArgs<User>
{
/// <summary>
/// Initializes a new instance of the <see cref="UserUpdatedEventArgs"/> class.
/// </summary>
/// <param name="arg">The user.</param>
public UserUpdatedEventArgs(User arg) : base(arg)
{
}
}
}
+53
View File
@@ -0,0 +1,53 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<PropertyGroup Condition=" '$(Stability)'=='Unstable'">
<!-- Include all symbols in the main nupkg until Azure Artifact Feed starts supporting ingesting NuGet symbol packages. -->
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
</PropertyGroup>
<PropertyGroup>
<Authors>Jellyfin Contributors</Authors>
<PackageId>Jellyfin.Data</PackageId>
<VersionPrefix>10.12.0</VersionPrefix>
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>
<!-- Code Analyzers -->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<PackageReference Include="IDisposableAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="SerilogAnalyzer" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" />
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\SharedVersion.cs" />
</ItemGroup>
</Project>
+68
View File
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Data.Queries;
/// <summary>
/// A class representing a query to the activity logs.
/// </summary>
public class ActivityLogQuery : PaginatedQuery
{
/// <summary>
/// Gets or sets a value indicating whether to take entries with a user id.
/// </summary>
public bool? HasUserId { get; set; }
/// <summary>
/// Gets or sets the minimum date to query for.
/// </summary>
public DateTime? MinDate { get; set; }
/// <summary>
/// Gets or sets the maximum date to query for.
/// </summary>
public DateTime? MaxDate { get; set; }
/// <summary>
/// Gets or sets the name filter.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Gets or sets the overview filter.
/// </summary>
public string? Overview { get; set; }
/// <summary>
/// Gets or sets the short overview filter.
/// </summary>
public string? ShortOverview { get; set; }
/// <summary>
/// Gets or sets the type filter.
/// </summary>
public string? Type { get; set; }
/// <summary>
/// Gets or sets the item filter.
/// </summary>
public Guid? ItemId { get; set; }
/// <summary>
/// Gets or sets the username filter.
/// </summary>
public string? Username { get; set; }
/// <summary>
/// Gets or sets the log level filter.
/// </summary>
public LogLevel? Severity { get; set; }
/// <summary>
/// Gets or sets the result ordering.
/// </summary>
public IReadOnlyCollection<(ActivityLogSortBy, SortOrder)>? OrderBy { get; set; }
}
+25
View File
@@ -0,0 +1,25 @@
using System;
namespace Jellyfin.Data.Queries
{
/// <summary>
/// A query to retrieve devices.
/// </summary>
public class DeviceQuery : PaginatedQuery
{
/// <summary>
/// Gets or sets the user id of the device.
/// </summary>
public Guid? UserId { get; set; }
/// <summary>
/// Gets or sets the device id.
/// </summary>
public string? DeviceId { get; set; }
/// <summary>
/// Gets or sets the access token.
/// </summary>
public string? AccessToken { get; set; }
}
}
+18
View File
@@ -0,0 +1,18 @@
namespace Jellyfin.Data.Queries
{
/// <summary>
/// An abstract class for paginated queries.
/// </summary>
public abstract class PaginatedQuery
{
/// <summary>
/// Gets or sets the index to start at.
/// </summary>
public int? Skip { get; set; }
/// <summary>
/// Gets or sets the maximum number of items to include.
/// </summary>
public int? Limit { get; set; }
}
}
+220
View File
@@ -0,0 +1,220 @@
using System;
using System.ComponentModel;
using System.Linq;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Data;
/// <summary>
/// Contains extension methods for manipulation of <see cref="User"/> entities.
/// </summary>
public static class UserEntityExtensions
{
/// <summary>
/// The values being delimited here are Guids, so commas work as they do not appear in Guids.
/// </summary>
private const char Delimiter = ',';
/// <summary>
/// Checks whether the user has the specified permission.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="kind">The permission kind.</param>
/// <returns><c>True</c> if the user has the specified permission.</returns>
public static bool HasPermission(this IHasPermissions entity, PermissionKind kind)
{
return entity.Permissions.FirstOrDefault(p => p.Kind == kind)?.Value ?? false;
}
/// <summary>
/// Sets the given permission kind to the provided value.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="kind">The permission kind.</param>
/// <param name="value">The value to set.</param>
public static void SetPermission(this IHasPermissions entity, PermissionKind kind, bool value)
{
var currentPermission = entity.Permissions.FirstOrDefault(p => p.Kind == kind);
if (currentPermission is null)
{
entity.Permissions.Add(new Permission(kind, value));
}
else
{
currentPermission.Value = value;
}
}
/// <summary>
/// Gets the user's preferences for the given preference kind.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="preference">The preference kind.</param>
/// <returns>A string array containing the user's preferences.</returns>
public static string[] GetPreference(this User entity, PreferenceKind preference)
{
var val = entity.Preferences.FirstOrDefault(p => p.Kind == preference)?.Value;
return string.IsNullOrEmpty(val) ? Array.Empty<string>() : val.Split(Delimiter);
}
/// <summary>
/// Gets the user's preferences for the given preference kind.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="preference">The preference kind.</param>
/// <typeparam name="T">Type of preference.</typeparam>
/// <returns>A {T} array containing the user's preference.</returns>
public static T[] GetPreferenceValues<T>(this User entity, PreferenceKind preference)
{
var val = entity.Preferences.FirstOrDefault(p => p.Kind == preference)?.Value;
if (string.IsNullOrEmpty(val))
{
return Array.Empty<T>();
}
// Convert array of {string} to array of {T}
var converter = TypeDescriptor.GetConverter(typeof(T));
var stringValues = val.Split(Delimiter);
var convertedCount = 0;
var parsedValues = new T[stringValues.Length];
for (var i = 0; i < stringValues.Length; i++)
{
try
{
var parsedValue = converter.ConvertFromString(stringValues[i].Trim());
if (parsedValue is not null)
{
parsedValues[convertedCount++] = (T)parsedValue;
}
}
catch (FormatException)
{
// Unable to convert value
}
}
return parsedValues[..convertedCount];
}
/// <summary>
/// Sets the specified preference to the given value.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="preference">The preference kind.</param>
/// <param name="values">The values.</param>
public static void SetPreference(this User entity, PreferenceKind preference, string[] values)
{
var value = string.Join(Delimiter, values);
var currentPreference = entity.Preferences.FirstOrDefault(p => p.Kind == preference);
if (currentPreference is null)
{
entity.Preferences.Add(new Preference(preference, value));
}
else
{
currentPreference.Value = value;
}
}
/// <summary>
/// Sets the specified preference to the given value.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="preference">The preference kind.</param>
/// <param name="values">The values.</param>
/// <typeparam name="T">The type of value.</typeparam>
public static void SetPreference<T>(this User entity, PreferenceKind preference, T[] values)
{
var value = string.Join(Delimiter, values);
var currentPreference = entity.Preferences.FirstOrDefault(p => p.Kind == preference);
if (currentPreference is null)
{
entity.Preferences.Add(new Preference(preference, value));
}
else
{
currentPreference.Value = value;
}
}
/// <summary>
/// Checks whether this user is currently allowed to use the server.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <returns><c>True</c> if the current time is within an access schedule, or there are no access schedules.</returns>
public static bool IsParentalScheduleAllowed(this User entity)
{
return entity.AccessSchedules.Count == 0
|| entity.AccessSchedules.Any(i => IsParentalScheduleAllowed(i, DateTime.UtcNow));
}
/// <summary>
/// Checks whether the provided folder is in this user's grouped folders.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="id">The Guid of the folder.</param>
/// <returns><c>True</c> if the folder is in the user's grouped folders.</returns>
public static bool IsFolderGrouped(this User entity, Guid id)
{
return Array.IndexOf(GetPreferenceValues<Guid>(entity, PreferenceKind.GroupedFolders), id) != -1;
}
/// <summary>
/// Initializes the default permissions for a user. Should only be called on user creation.
/// </summary>
/// <param name="entity">The entity to update.</param>
// TODO: make these user configurable?
public static void AddDefaultPermissions(this User entity)
{
entity.Permissions.Add(new Permission(PermissionKind.IsAdministrator, false));
entity.Permissions.Add(new Permission(PermissionKind.IsDisabled, false));
entity.Permissions.Add(new Permission(PermissionKind.IsHidden, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableAllChannels, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableAllDevices, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableAllFolders, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableContentDeletion, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableContentDownloading, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableMediaConversion, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableMediaPlayback, true));
entity.Permissions.Add(new Permission(PermissionKind.EnablePlaybackRemuxing, true));
entity.Permissions.Add(new Permission(PermissionKind.EnablePublicSharing, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableRemoteAccess, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableSyncTranscoding, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableAudioPlaybackTranscoding, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableLiveTvAccess, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableLiveTvManagement, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableSharedDeviceControl, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableVideoPlaybackTranscoding, true));
entity.Permissions.Add(new Permission(PermissionKind.ForceRemoteSourceTranscoding, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableRemoteControlOfOtherUsers, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableCollectionManagement, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableSubtitleManagement, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableLyricManagement, false));
}
/// <summary>
/// Initializes the default preferences. Should only be called on user creation.
/// </summary>
/// <param name="entity">The entity to update.</param>
public static void AddDefaultPreferences(this User entity)
{
foreach (var val in Enum.GetValues<PreferenceKind>())
{
entity.Preferences.Add(new Preference(val, string.Empty));
}
}
private static bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date)
{
var localTime = date.ToLocalTime();
var hour = localTime.TimeOfDay.TotalHours;
var currentDayOfWeek = localTime.DayOfWeek;
return schedule.DayOfWeek.Contains(currentDayOfWeek)
&& hour >= schedule.StartHour
&& hour <= schedule.EndHour;
}
}
@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
@@ -0,0 +1,27 @@
is_global = true
build_property.TargetFramework = net10.0
build_property.TargetFramework = net10.0
build_property.TargetFrameworkIdentifier = .NETCoreApp
build_property.TargetFrameworkIdentifier = .NETCoreApp
build_property.TargetFrameworkVersion = v10.0
build_property.TargetFrameworkVersion = v10.0
build_property.TargetPlatformMinVersion =
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = Jellyfin.Data
build_property.ProjectDir = /srv/common_drive/Projects/pgsql-jellyfin/Jellyfin.Data/
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.EffectiveAnalysisLevelStyle = 10.0
build_property.EnableCodeStyleSeverity =
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/wjones/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/wjones/.nuget/packages/</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="/home/wjones/.nuget/packages/" />
</ItemGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore/10.0.3/buildTransitive/net10.0/Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore/10.0.3/buildTransitive/net10.0/Microsoft.EntityFrameworkCore.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.props" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.props')" />
</ImportGroup>
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<PkgStyleCop_Analyzers_Unstable Condition=" '$(PkgStyleCop_Analyzers_Unstable)' == '' ">/home/wjones/.nuget/packages/stylecop.analyzers.unstable/1.2.0.556</PkgStyleCop_Analyzers_Unstable>
<PkgSmartAnalyzers_MultithreadingAnalyzer Condition=" '$(PkgSmartAnalyzers_MultithreadingAnalyzer)' == '' ">/home/wjones/.nuget/packages/smartanalyzers.multithreadinganalyzer/1.1.31</PkgSmartAnalyzers_MultithreadingAnalyzer>
<PkgSerilogAnalyzer Condition=" '$(PkgSerilogAnalyzer)' == '' ">/home/wjones/.nuget/packages/seriloganalyzer/0.15.0</PkgSerilogAnalyzer>
<PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers)' == '' ">/home/wjones/.nuget/packages/microsoft.codeanalysis.bannedapianalyzers/4.14.0</PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers>
<PkgIDisposableAnalyzers Condition=" '$(PkgIDisposableAnalyzers)' == '' ">/home/wjones/.nuget/packages/idisposableanalyzers/4.0.8</PkgIDisposableAnalyzers>
</PropertyGroup>
</Project>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Options.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Logging.Abstractions.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.targets')" />
</ImportGroup>
</Project>
File diff suppressed because it is too large Load Diff
+30
View File
@@ -0,0 +1,30 @@
{
"version": 2,
"dgSpecHash": "EHhu2bd8aNc=",
"success": true,
"projectFilePath": "/srv/common_drive/Projects/pgsql-jellyfin/Jellyfin.Data/Jellyfin.Data.csproj",
"expectedPackageFiles": [
"/home/wjones/.nuget/packages/idisposableanalyzers/4.0.8/idisposableanalyzers.4.0.8.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.codeanalysis.bannedapianalyzers/4.14.0/microsoft.codeanalysis.bannedapianalyzers.4.14.0.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore/10.0.3/microsoft.entityframeworkcore.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore.abstractions/10.0.3/microsoft.entityframeworkcore.abstractions.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore.analyzers/10.0.3/microsoft.entityframeworkcore.analyzers.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore.relational/10.0.3/microsoft.entityframeworkcore.relational.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.extensions.caching.abstractions/10.0.3/microsoft.extensions.caching.abstractions.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.extensions.caching.memory/10.0.3/microsoft.extensions.caching.memory.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.extensions.configuration.abstractions/10.0.3/microsoft.extensions.configuration.abstractions.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.extensions.dependencyinjection/10.0.3/microsoft.extensions.dependencyinjection.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.extensions.dependencyinjection.abstractions/10.0.3/microsoft.extensions.dependencyinjection.abstractions.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.extensions.logging/10.0.3/microsoft.extensions.logging.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.extensions.logging.abstractions/10.0.3/microsoft.extensions.logging.abstractions.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.extensions.options/10.0.3/microsoft.extensions.options.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.extensions.primitives/10.0.3/microsoft.extensions.primitives.10.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/polly/8.6.5/polly.8.6.5.nupkg.sha512",
"/home/wjones/.nuget/packages/polly.core/8.6.5/polly.core.8.6.5.nupkg.sha512",
"/home/wjones/.nuget/packages/seriloganalyzer/0.15.0/seriloganalyzer.0.15.0.nupkg.sha512",
"/home/wjones/.nuget/packages/smartanalyzers.multithreadinganalyzer/1.1.31/smartanalyzers.multithreadinganalyzer.1.1.31.nupkg.sha512",
"/home/wjones/.nuget/packages/stylecop.analyzers/1.2.0-beta.556/stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
"/home/wjones/.nuget/packages/stylecop.analyzers.unstable/1.2.0.556/stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512"
],
"logs": []
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
17714532046900000
@@ -0,0 +1 @@
17715044199300000