Compare commits

...

39 Commits

Author SHA1 Message Date
Joshua M. Boniface
b49cd1d301 Fix Release ref for Fedora 2020-08-30 16:45:31 -04:00
Joshua M. Boniface
491b06f1dd Bump version to 10.6.4 2020-08-30 16:44:49 -04:00
Bond-009
37f2743780 Merge pull request #3953 from crobibero/dotnetglob
bump DotNet.Glob

(cherry picked from commit 03c89fa717)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-30 16:09:28 -04:00
Joshua M. Boniface
c3ef1f56f6 Merge pull request #4001 from brianjmurrell/patch-1
Add an empty %files section to main package
2020-08-27 16:47:19 -04:00
Brian J. Murrell
098cd5c388 Bump the Release
To reflect the spec change, adding the %files.

Signed-off-by: Brian J. Murrell <brian@interlinx.bc.ca>
2020-08-27 16:36:24 -04:00
Brian J. Murrell
eb18ab3403 Add an empty %files section to main package
In order for the jellyfin meta-package to exist, there has to be an empty
%files section for it.

Fixes: #3701

Signed-off-by: Brian J. Murrell <brian@interlinx.bc.ca>
2020-08-27 11:34:41 -04:00
Joshua M. Boniface
16e3bd094f Bump version to 10.6.3 2020-08-16 20:19:54 -04:00
Joshua M. Boniface
8d1075eb77 Merge pull request #3831 from joshuaboniface/newer-docker-dotnet
Bump to .NET Core SDK 3.1.302

(cherry picked from commit 751affa50a)
2020-08-16 20:19:46 -04:00
Joshua M. Boniface
973fcdbaa1 Bump version to 10.6.2 2020-08-02 20:53:04 -04:00
dkanada
5ea5b9a654 Merge pull request #3795 from anthonylavado/master
Update to newer Jellyfin.XMLTV

(cherry picked from commit 714a6f04ef)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:50:44 -04:00
dkanada
e657781459 Merge pull request #3792 from cvium/fix_tmdb_deserialize
TMDb: Change Budget and Revenue to long to avoid overflow
(cherry picked from commit 254ef6bc0d)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:50:44 -04:00
Bond-009
4e6e310b71 Merge pull request #3790 from cvium/fewer_string_allocs
Remove some unnecessary string allocations

(cherry picked from commit 43fa983414)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:50:44 -04:00
Joshua M. Boniface
43ade73be4 Merge pull request #3761 from cvium/fix_mem_leak
Fix DI memory leak

(cherry picked from commit 9bf6222597)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:37:11 -04:00
Anthony Lavado
f88e9b2678 Merge pull request #3760 from thornbill/true-or-false
Fix inverted logic for LAN IP detection

(cherry picked from commit 4bad529fcb)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:37:11 -04:00
Bond-009
0eb0b15b2a Merge pull request #3757 from jellyfin/update_blurhashsharp
Update BlurHashSharp and set max size to 128x128

(cherry picked from commit ee3fae497c)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:37:11 -04:00
Joshua M. Boniface
7402679a99 Merge pull request #3728 from jellyfin/qsv-cutter
Adjust priority in outputSizeParam cutter

(cherry picked from commit 47e63def20)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:37:11 -04:00
Anthony Lavado
e276532f2f Merge pull request #3727 from K900/patch-1
Fix #3624

(cherry picked from commit 06db5f8bca)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:37:01 -04:00
Joshua M. Boniface
b1250e2e83 Merge pull request #3725 from joshuaboniface/fix-ci-docker
Flip quoting in variable set command

(cherry picked from commit 8c1dab146c)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:35:31 -04:00
Anthony Lavado
35d3ad1a55 Merge pull request #3723 from joshuaboniface/fix-ci-docker
Get and tag with the actual release version in CI

(cherry picked from commit b207907e1b)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:35:31 -04:00
Joshua M. Boniface
02f36373c2 Merge pull request #3720 from joshuaboniface/fix-bump-version
Fix bump_version so it works properly

(cherry picked from commit dc0f1788f4)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-08-02 20:35:31 -04:00
Joshua M. Boniface
3b73e74ce5 Bump version to 10.6.1 2020-07-27 18:59:16 -04:00
Anthony Lavado
8bb03e8f91 Merge pull request #3711 from yrjyrj123/fix_hw_decoder_for_macos
Fix the problem that hardware decoding cannot be used on macOS.

(cherry picked from commit ea0489a98e)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Anthony Lavado
3e742e99a5 Merge pull request #3704 from oddstr13/pr-dotdir-sample-1
Don't ignore dot directories or movies/episodes with sample in their name.

(cherry picked from commit 6eb3e736c6)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
dkanada
ad3a96267e Merge pull request #3703 from oddstr13/pr-username-space-1
Allow space in username

(cherry picked from commit 8ab800508b)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Anthony Lavado
8b42ef451c Merge pull request #3699 from oddstr13/pr-embedded-subs-1
Fix embedded subtitles

(cherry picked from commit bfecfab538)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Joshua M. Boniface
4ce16489a4 Merge pull request #3675 from ferferga/fix-typo
Fix typo in debian config file

(cherry picked from commit 1a9adf283a)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Bond-009
809651ceaf Merge pull request #3663 from crobibero/efcore-leak
Add missing usings to UserManager

(cherry picked from commit 6b11cccb7f)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Anthony Lavado
6547ae46ce Merge pull request #3660 from crobibero/plugin-config-location
Force plugin config location

(cherry picked from commit 468a7fea4c)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Bond-009
cbf6ef4dbd Merge pull request #3649 from thornbill/fix-epg-update-maybe
Skip image processing for live tv sources

(cherry picked from commit e9758bde2a)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Bond-009
e4ce72e7bb Merge pull request #3642 from crobibero/plugin-repo-x2
Try adding plugin repository again

(cherry picked from commit a86d8d1757)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Anthony Lavado
3b758c3a66 Merge pull request #3634 from crobibero/plugin-config
fix built in plugin js

(cherry picked from commit f23e119a68)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Bond-009
dadd42e574 Merge pull request #3620 from BaronGreenback/IPFix
Fix for #3607 and #3515

(cherry picked from commit 0750357916)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
dkanada
349b789492 Merge pull request #3616 from crobibero/migration-new-install
Allow migration to optionally run on fresh install

(cherry picked from commit 107cf21f26)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Bond-009
0ee0aa8941 Merge pull request #3615 from jellyfin/qsv-comet-lake
Fix QSV device creation on Comet Lake

(cherry picked from commit 6de6583cbd)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Bond-009
94dbdd9f98 Merge pull request #3604 from joshuaboniface/fix-bad-deps
Fix bad Debuntu dependencies

(cherry picked from commit 41c4cfe0af)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Bond-009
9875f30836 Merge pull request #3602 from crobibero/user-change-case
Fix username case change

(cherry picked from commit 8f11e057a2)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Anthony Lavado
a717a531bc Merge pull request #3576 from HelloWorld017/fix/sami-utf16
Fix SAMI UTF-16 Encoding Bug

(cherry picked from commit 0cb2cd9456)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Bond-009
d04e255a79 Merge pull request #3552 from BaronGreenback/NotificationFix
Fixes #3551 (Notifications Serialization error)

(cherry picked from commit 944fdb4c62)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
Bond-009
2fd902f1b2 Merge pull request #3521 from sachk/master
Fix support for mixed-protocol subtitles

(cherry picked from commit 323fc576a5)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-07-27 18:53:09 -04:00
51 changed files with 451 additions and 273 deletions

View File

@@ -80,7 +80,15 @@ jobs:
pool:
vmImage: 'ubuntu-latest'
variables:
- name: JellyfinVersion
value: 0.0.0
steps:
- script: echo "##vso[task.setvariable variable=JellyfinVersion]$( awk -F '/' '{ print $NF }' <<<'$(Build.SourceBranch)' | sed 's/^v//' )"
displayName: Set release version (stable)
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags')
- task: Docker@2
displayName: 'Push Unstable Image'
condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/master')
@@ -105,7 +113,7 @@ jobs:
containerRegistry: Docker Hub
tags: |
stable-$(Build.BuildNumber)-$(BuildConfiguration)
stable-$(BuildConfiguration)
$(JellyfinVersion)-$(BuildConfiguration)
- job: CollectArtifacts
displayName: 'Collect Artifacts'

View File

@@ -400,6 +400,8 @@ namespace Emby.Server.Implementations.Data
"OwnerId"
};
private static readonly string _retriveItemColumnsSelectQuery = $"select {string.Join(',', _retriveItemColumns)} from TypedBaseItems where guid = @guid";
private static readonly string[] _mediaStreamSaveColumns =
{
"ItemId",
@@ -439,6 +441,12 @@ namespace Emby.Server.Implementations.Data
"ColorTransfer"
};
private static readonly string _mediaStreamSaveColumnsInsertQuery =
$"insert into mediastreams ({string.Join(',', _mediaStreamSaveColumns)}) values ";
private static readonly string _mediaStreamSaveColumnsSelectQuery =
$"select {string.Join(',', _mediaStreamSaveColumns)} from mediastreams where ItemId=@ItemId";
private static readonly string[] _mediaAttachmentSaveColumns =
{
"ItemId",
@@ -450,102 +458,15 @@ namespace Emby.Server.Implementations.Data
"MIMEType"
};
private static readonly string _mediaAttachmentSaveColumnsSelectQuery =
$"select {string.Join(',', _mediaAttachmentSaveColumns)} from mediaattachments where ItemId=@ItemId";
private static readonly string _mediaAttachmentInsertPrefix;
private static string GetSaveItemCommandText()
{
var saveColumns = new[]
{
"guid",
"type",
"data",
"Path",
"StartDate",
"EndDate",
"ChannelId",
"IsMovie",
"IsSeries",
"EpisodeTitle",
"IsRepeat",
"CommunityRating",
"CustomRating",
"IndexNumber",
"IsLocked",
"Name",
"OfficialRating",
"MediaType",
"Overview",
"ParentIndexNumber",
"PremiereDate",
"ProductionYear",
"ParentId",
"Genres",
"InheritedParentalRatingValue",
"SortName",
"ForcedSortName",
"RunTimeTicks",
"Size",
"DateCreated",
"DateModified",
"PreferredMetadataLanguage",
"PreferredMetadataCountryCode",
"Width",
"Height",
"DateLastRefreshed",
"DateLastSaved",
"IsInMixedFolder",
"LockedFields",
"Studios",
"Audio",
"ExternalServiceId",
"Tags",
"IsFolder",
"UnratedType",
"TopParentId",
"TrailerTypes",
"CriticRating",
"CleanName",
"PresentationUniqueKey",
"OriginalTitle",
"PrimaryVersionId",
"DateLastMediaAdded",
"Album",
"IsVirtualItem",
"SeriesName",
"UserDataKey",
"SeasonName",
"SeasonId",
"SeriesId",
"ExternalSeriesId",
"Tagline",
"ProviderIds",
"Images",
"ProductionLocations",
"ExtraIds",
"TotalBitrate",
"ExtraType",
"Artists",
"AlbumArtists",
"ExternalId",
"SeriesPresentationUniqueKey",
"ShowId",
"OwnerId"
};
var saveItemCommandCommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns) + ") values (";
for (var i = 0; i < saveColumns.Length; i++)
{
if (i != 0)
{
saveItemCommandCommandText += ",";
}
saveItemCommandCommandText += "@" + saveColumns[i];
}
return saveItemCommandCommandText + ")";
}
private const string SaveItemCommandText =
@"replace into TypedBaseItems
(guid,type,data,Path,StartDate,EndDate,ChannelId,IsMovie,IsSeries,EpisodeTitle,IsRepeat,CommunityRating,CustomRating,IndexNumber,IsLocked,Name,OfficialRating,MediaType,Overview,ParentIndexNumber,PremiereDate,ProductionYear,ParentId,Genres,InheritedParentalRatingValue,SortName,ForcedSortName,RunTimeTicks,Size,DateCreated,DateModified,PreferredMetadataLanguage,PreferredMetadataCountryCode,Width,Height,DateLastRefreshed,DateLastSaved,IsInMixedFolder,LockedFields,Studios,Audio,ExternalServiceId,Tags,IsFolder,UnratedType,TopParentId,TrailerTypes,CriticRating,CleanName,PresentationUniqueKey,OriginalTitle,PrimaryVersionId,DateLastMediaAdded,Album,IsVirtualItem,SeriesName,UserDataKey,SeasonName,SeasonId,SeriesId,ExternalSeriesId,Tagline,ProviderIds,Images,ProductionLocations,ExtraIds,TotalBitrate,ExtraType,Artists,AlbumArtists,ExternalId,SeriesPresentationUniqueKey,ShowId,OwnerId)
values (@guid,@type,@data,@Path,@StartDate,@EndDate,@ChannelId,@IsMovie,@IsSeries,@EpisodeTitle,@IsRepeat,@CommunityRating,@CustomRating,@IndexNumber,@IsLocked,@Name,@OfficialRating,@MediaType,@Overview,@ParentIndexNumber,@PremiereDate,@ProductionYear,@ParentId,@Genres,@InheritedParentalRatingValue,@SortName,@ForcedSortName,@RunTimeTicks,@Size,@DateCreated,@DateModified,@PreferredMetadataLanguage,@PreferredMetadataCountryCode,@Width,@Height,@DateLastRefreshed,@DateLastSaved,@IsInMixedFolder,@LockedFields,@Studios,@Audio,@ExternalServiceId,@Tags,@IsFolder,@UnratedType,@TopParentId,@TrailerTypes,@CriticRating,@CleanName,@PresentationUniqueKey,@OriginalTitle,@PrimaryVersionId,@DateLastMediaAdded,@Album,@IsVirtualItem,@SeriesName,@UserDataKey,@SeasonName,@SeasonId,@SeriesId,@ExternalSeriesId,@Tagline,@ProviderIds,@Images,@ProductionLocations,@ExtraIds,@TotalBitrate,@ExtraType,@Artists,@AlbumArtists,@ExternalId,@SeriesPresentationUniqueKey,@ShowId,@OwnerId)";
/// <summary>
/// Save a standard item in the repo.
@@ -636,7 +557,7 @@ namespace Emby.Server.Implementations.Data
{
var statements = PrepareAll(db, new string[]
{
GetSaveItemCommandText(),
SaveItemCommandText,
"delete from AncestorIds where ItemId=@ItemId"
}).ToList();
@@ -1225,7 +1146,7 @@ namespace Emby.Server.Implementations.Data
using (var connection = GetConnection(true))
{
using (var statement = PrepareStatement(connection, "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems where guid = @guid"))
using (var statement = PrepareStatement(connection, _retriveItemColumnsSelectQuery))
{
statement.TryBind("@guid", id);
@@ -5890,10 +5811,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
throw new ArgumentNullException(nameof(query));
}
var cmdText = "select "
+ string.Join(",", _mediaStreamSaveColumns)
+ " from mediastreams where"
+ " ItemId=@ItemId";
var cmdText = _mediaStreamSaveColumnsSelectQuery;
if (query.Type.HasValue)
{
@@ -5972,15 +5890,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
while (startIndex < streams.Count)
{
var insertText = new StringBuilder("insert into mediastreams (");
foreach (var column in _mediaStreamSaveColumns)
{
insertText.Append(column).Append(',');
}
// Remove last comma
insertText.Length--;
insertText.Append(") values ");
var insertText = new StringBuilder(_mediaStreamSaveColumnsInsertQuery);
var endIndex = Math.Min(streams.Count, startIndex + Limit);
@@ -6247,10 +6157,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
throw new ArgumentNullException(nameof(query));
}
var cmdText = "select "
+ string.Join(",", _mediaAttachmentSaveColumns)
+ " from mediaattachments where"
+ " ItemId=@ItemId";
var cmdText = _mediaAttachmentSaveColumnsSelectQuery;
if (query.Index.HasValue)
{

View File

@@ -25,7 +25,7 @@
<ItemGroup>
<PackageReference Include="IPNetwork2" Version="2.5.211" />
<PackageReference Include="Jellyfin.XmlTv" Version="10.6.0-pre1" />
<PackageReference Include="Jellyfin.XmlTv" Version="10.6.2" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
@@ -43,7 +43,7 @@
<PackageReference Include="ServiceStack.Text.Core" Version="5.9.0" />
<PackageReference Include="sharpcompress" Version="0.25.1" />
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" />
<PackageReference Include="DotNet.Glob" Version="3.0.9" />
<PackageReference Include="DotNet.Glob" Version="3.1.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -18,7 +18,21 @@ namespace Emby.Server.Implementations.Library
{
"**/small.jpg",
"**/albumart.jpg",
"**/*sample*",
// We have neither non-greedy matching or character group repetitions, working around that here.
// https://github.com/dazinator/DotNet.Glob#patterns
// .*/sample\..{1,5}
"**/sample.?",
"**/sample.??",
"**/sample.???", // Matches sample.mkv
"**/sample.????", // Matches sample.webm
"**/sample.?????",
"**/*.sample.?",
"**/*.sample.??",
"**/*.sample.???",
"**/*.sample.????",
"**/*.sample.?????",
"**/sample/*",
// Directories
"**/metadata/**",
@@ -64,10 +78,13 @@ namespace Emby.Server.Implementations.Library
"**/.grab/**",
"**/.grab",
// Unix hidden files and directories
"**/.*/**",
// Unix hidden files
"**/.*",
// Mac - if you ever remove the above.
// "**/._*",
// "**/.DS_Store",
// thumbs.db
"**/thumbs.db",

View File

@@ -1876,7 +1876,8 @@ namespace Emby.Server.Implementations.Library
}
var outdated = forceUpdate ? item.ImageInfos.Where(i => i.Path != null).ToArray() : item.ImageInfos.Where(ImageNeedsRefresh).ToArray();
if (outdated.Length == 0)
// Skip image processing if current or live tv source
if (outdated.Length == 0 || item.SourceType != SourceType.Library)
{
RegisterItem(item);
return;

View File

@@ -152,7 +152,12 @@ namespace Emby.Server.Implementations.Networking
return true;
}
byte[] octet = IPAddress.Parse(endpoint).GetAddressBytes();
if (!IPAddress.TryParse(endpoint, out var ipAddress))
{
return false;
}
byte[] octet = ipAddress.GetAddressBytes();
if ((octet[0] == 10) ||
(octet[0] == 172 && (octet[1] >= 16 && octet[1] <= 31)) || // RFC1918
@@ -160,7 +165,7 @@ namespace Emby.Server.Implementations.Networking
(octet[0] == 127) || // RFC1122
(octet[0] == 169 && octet[1] == 254)) // RFC3927
{
return false;
return true;
}
if (checkSubnets && IsInPrivateAddressSpaceAndLocalSubnet(endpoint))
@@ -268,6 +273,12 @@ namespace Emby.Server.Implementations.Networking
string excludeAddress = "[" + addressString + "]";
var subnets = LocalSubnetsFn();
// Include any address if LAN subnets aren't specified
if (subnets.Length == 0)
{
return true;
}
// Exclude any addresses if they appear in the LAN list in [ ]
if (Array.IndexOf(subnets, excludeAddress) != -1)
{

View File

@@ -18,8 +18,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BlurHashSharp" Version="1.0.1" />
<PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.0.0" />
<PackageReference Include="BlurHashSharp" Version="1.1.0" />
<PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.1.0" />
<PackageReference Include="SkiaSharp" Version="1.68.3" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="1.68.3" />
<PackageReference Include="Jellyfin.SkiaSharp.NativeAssets.LinuxArm" Version="1.68.1" />

View File

@@ -237,7 +237,8 @@ namespace Jellyfin.Drawing.Skia
throw new ArgumentNullException(nameof(path));
}
return BlurHashEncoder.Encode(xComp, yComp, path);
// Any larger than 128x128 is too slow and there's no visually discernible difference
return BlurHashEncoder.Encode(xComp, yComp, path, 128, 128);
}
private static bool HasDiacritics(string text)

View File

@@ -1,5 +1,6 @@
#pragma warning disable CS1591
using System;
using System.Linq;
using Jellyfin.Data;
using Jellyfin.Data.Entities;
@@ -133,6 +134,18 @@ namespace Jellyfin.Server.Implementations
return base.SaveChanges();
}
/// <inheritdoc/>
public override void Dispose()
{
foreach (var entry in ChangeTracker.Entries())
{
entry.State = EntityState.Detached;
}
GC.SuppressFinalize(this);
base.Dispose();
}
/// <inheritdoc />
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{

View File

@@ -1,4 +1,6 @@
using System;
using System.IO;
using MediaBrowser.Common.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
@@ -10,15 +12,20 @@ namespace Jellyfin.Server.Implementations
public class JellyfinDbProvider
{
private readonly IServiceProvider _serviceProvider;
private readonly IApplicationPaths _appPaths;
/// <summary>
/// Initializes a new instance of the <see cref="JellyfinDbProvider"/> class.
/// </summary>
/// <param name="serviceProvider">The application's service provider.</param>
public JellyfinDbProvider(IServiceProvider serviceProvider)
/// <param name="appPaths">The application paths.</param>
public JellyfinDbProvider(IServiceProvider serviceProvider, IApplicationPaths appPaths)
{
_serviceProvider = serviceProvider;
serviceProvider.GetRequiredService<JellyfinDb>().Database.Migrate();
_appPaths = appPaths;
using var jellyfinDb = CreateContext();
jellyfinDb.Database.Migrate();
}
/// <summary>
@@ -27,7 +34,8 @@ namespace Jellyfin.Server.Implementations
/// <returns>The newly created context.</returns>
public JellyfinDb CreateContext()
{
return _serviceProvider.GetRequiredService<JellyfinDb>();
var contextOptions = new DbContextOptionsBuilder<JellyfinDb>().UseSqlite($"Filename={Path.Combine(_appPaths.DataPath, "jellyfin.db")}");
return ActivatorUtilities.CreateInstance<JellyfinDb>(_serviceProvider, contextOptions.Options);
}
}
}

View File

@@ -102,7 +102,16 @@ namespace Jellyfin.Server.Implementations.Users
}
/// <inheritdoc/>
public IEnumerable<Guid> UsersIds => _dbProvider.CreateContext().Users.Select(u => u.Id);
public IEnumerable<Guid> UsersIds
{
get
{
using var dbContext = _dbProvider.CreateContext();
return dbContext.Users
.Select(user => user.Id)
.ToList();
}
}
/// <inheritdoc/>
public User? GetUserById(Guid id)
@@ -152,12 +161,12 @@ namespace Jellyfin.Server.Implementations.Users
throw new ArgumentException("Invalid username", nameof(newName));
}
if (user.Username.Equals(newName, StringComparison.OrdinalIgnoreCase))
if (user.Username.Equals(newName, StringComparison.Ordinal))
{
throw new ArgumentException("The new and old names must be different.");
}
if (Users.Any(u => u.Id != user.Id && u.Username.Equals(newName, StringComparison.OrdinalIgnoreCase)))
if (Users.Any(u => u.Id != user.Id && u.Username.Equals(newName, StringComparison.Ordinal)))
{
throw new ArgumentException(string.Format(
CultureInfo.InvariantCulture,
@@ -583,18 +592,13 @@ namespace Jellyfin.Server.Implementations.Users
}
var defaultName = Environment.UserName;
if (string.IsNullOrWhiteSpace(defaultName))
if (string.IsNullOrWhiteSpace(defaultName) || !IsValidUsername(defaultName))
{
defaultName = "MyJellyfinUser";
}
_logger.LogWarning("No users, creating one with username {UserName}", defaultName);
if (!IsValidUsername(defaultName))
{
throw new ArgumentException("Provided username is not valid!", defaultName);
}
var newUser = CreateUser(defaultName);
newUser.SetPermission(PermissionKind.IsAdministrator, true);
newUser.SetPermission(PermissionKind.EnableContentDeletion, true);
@@ -637,7 +641,7 @@ namespace Jellyfin.Server.Implementations.Users
/// <inheritdoc/>
public void UpdateConfiguration(Guid userId, UserConfiguration config)
{
var dbContext = _dbProvider.CreateContext();
using var dbContext = _dbProvider.CreateContext();
var user = dbContext.Users
.Include(u => u.Permissions)
.Include(u => u.Preferences)
@@ -670,7 +674,7 @@ namespace Jellyfin.Server.Implementations.Users
/// <inheritdoc/>
public void UpdatePolicy(Guid userId, UserPolicy policy)
{
var dbContext = _dbProvider.CreateContext();
using var dbContext = _dbProvider.CreateContext();
var user = dbContext.Users
.Include(u => u.Permissions)
.Include(u => u.Preferences)
@@ -749,8 +753,8 @@ namespace Jellyfin.Server.Implementations.Users
{
// This is some regex that matches only on unicode "word" characters, as well as -, _ and @
// In theory this will cut out most if not all 'control' characters which should help minimize any weirdness
// Usernames can contain letters (a-z + whatever else unicode is cool with), numbers (0-9), at-signs (@), dashes (-), underscores (_), apostrophes ('), and periods (.)
return Regex.IsMatch(name, @"^[\w\-'._@]*$");
// Usernames can contain letters (a-z + whatever else unicode is cool with), numbers (0-9), at-signs (@), dashes (-), underscores (_), apostrophes ('), periods (.) and spaces ( )
return Regex.IsMatch(name, @"^[\w\ \-'._@]*$");
}
private IAuthenticationProvider GetAuthenticationProvider(User user)

View File

@@ -63,11 +63,12 @@ namespace Jellyfin.Server
Logger.LogWarning($"Skia not available. Will fallback to {nameof(NullImageEncoder)}.");
}
// TODO: Set up scoping and use AddDbContextPool
serviceCollection.AddDbContext<JellyfinDb>(
options => options
.UseSqlite($"Filename={Path.Combine(ApplicationPaths.DataPath, "jellyfin.db")}"),
ServiceLifetime.Transient);
// TODO: Set up scoping and use AddDbContextPool,
// can't register as Transient since tracking transient in GC is funky
// serviceCollection.AddDbContext<JellyfinDb>(
// options => options
// .UseSqlite($"Filename={Path.Combine(ApplicationPaths.DataPath, "jellyfin.db")}"),
// ServiceLifetime.Transient);
serviceCollection.AddSingleton<JellyfinDbProvider>();

View File

@@ -17,6 +17,11 @@ namespace Jellyfin.Server.Migrations
/// </summary>
public string Name { get; }
/// <summary>
/// Gets a value indicating whether to perform migration on a new install.
/// </summary>
public bool PerformOnNewInstall { get; }
/// <summary>
/// Execute the migration routine.
/// </summary>

View File

@@ -21,7 +21,8 @@ namespace Jellyfin.Server.Migrations
typeof(Routines.MigrateActivityLogDb),
typeof(Routines.RemoveDuplicateExtras),
typeof(Routines.AddDefaultPluginRepository),
typeof(Routines.MigrateUserDb)
typeof(Routines.MigrateUserDb),
typeof(Routines.ReaddDefaultPluginRepository)
};
/// <summary>
@@ -43,9 +44,8 @@ namespace Jellyfin.Server.Migrations
// If startup wizard is not finished, this is a fresh install.
// Don't run any migrations, just mark all of them as applied.
logger.LogInformation("Marking all known migrations as applied because this is a fresh install");
migrationOptions.Applied.AddRange(migrations.Select(m => (m.Id, m.Name)));
migrationOptions.Applied.AddRange(migrations.Where(m => !m.PerformOnNewInstall).Select(m => (m.Id, m.Name)));
host.ServerConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions);
return;
}
var appliedMigrationIds = migrationOptions.Applied.Select(m => m.Id).ToHashSet();

View File

@@ -32,6 +32,9 @@ namespace Jellyfin.Server.Migrations.Routines
/// <inheritdoc/>
public string Name => "AddDefaultPluginRepository";
/// <inheritdoc/>
public bool PerformOnNewInstall => true;
/// <inheritdoc/>
public void Perform()
{

View File

@@ -48,6 +48,9 @@ namespace Jellyfin.Server.Migrations.Routines
/// <inheritdoc/>
public string Name => "CreateLoggingConfigHeirarchy";
/// <inheritdoc/>
public bool PerformOnNewInstall => false;
/// <inheritdoc/>
public void Perform()
{

View File

@@ -25,6 +25,9 @@ namespace Jellyfin.Server.Migrations.Routines
/// <inheritdoc/>
public string Name => "DisableTranscodingThrottling";
/// <inheritdoc/>
public bool PerformOnNewInstall => false;
/// <inheritdoc/>
public void Perform()
{

View File

@@ -41,6 +41,9 @@ namespace Jellyfin.Server.Migrations.Routines
/// <inheritdoc/>
public string Name => "MigrateActivityLogDatabase";
/// <inheritdoc/>
public bool PerformOnNewInstall => false;
/// <inheritdoc/>
public void Perform()
{

View File

@@ -54,6 +54,9 @@ namespace Jellyfin.Server.Migrations.Routines
/// <inheritdoc/>
public string Name => "MigrateUserDatabase";
/// <inheritdoc/>
public bool PerformOnNewInstall => false;
/// <inheritdoc/>
public void Perform()
{

View File

@@ -0,0 +1,49 @@
using System;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Updates;
namespace Jellyfin.Server.Migrations.Routines
{
/// <summary>
/// Migration to initialize system configuration with the default plugin repository.
/// </summary>
public class ReaddDefaultPluginRepository : IMigrationRoutine
{
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly RepositoryInfo _defaultRepositoryInfo = new RepositoryInfo
{
Name = "Jellyfin Stable",
Url = "https://repo.jellyfin.org/releases/plugin/manifest-stable.json"
};
/// <summary>
/// Initializes a new instance of the <see cref="ReaddDefaultPluginRepository"/> class.
/// </summary>
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
public ReaddDefaultPluginRepository(IServerConfigurationManager serverConfigurationManager)
{
_serverConfigurationManager = serverConfigurationManager;
}
/// <inheritdoc/>
public Guid Id => Guid.Parse("5F86E7F6-D966-4C77-849D-7A7B40B68C4E");
/// <inheritdoc/>
public string Name => "ReaddDefaultPluginRepository";
/// <inheritdoc/>
public bool PerformOnNewInstall => true;
/// <inheritdoc/>
public void Perform()
{
// Only add if repository list is empty
if (_serverConfigurationManager.Configuration.PluginRepositories.Count == 0)
{
_serverConfigurationManager.Configuration.PluginRepositories.Add(_defaultRepositoryInfo);
_serverConfigurationManager.SaveConfiguration();
}
}
}
}

View File

@@ -29,6 +29,9 @@ namespace Jellyfin.Server.Migrations.Routines
/// <inheritdoc/>
public string Name => "RemoveDuplicateExtras";
/// <inheritdoc/>
public bool PerformOnNewInstall => false;
/// <inheritdoc/>
public void Perform()
{

View File

@@ -456,11 +456,12 @@ namespace MediaBrowser.Controller.MediaEncoding
var isQsvEncoder = outputVideoCodec.IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1;
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
var isMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
if (!IsCopyCodec(outputVideoCodec))
{
if (state.IsVideoRequest
&& IsVaapiSupported(state)
&& _mediaEncoder.SupportsHwaccel("vaapi")
&& string.Equals(encodingOptions.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
{
if (isVaapiDecoder)
@@ -495,13 +496,13 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else
{
arg.Append("-hwaccel qsv -init_hw_device qsv=hw ");
arg.Append("-hwaccel qsv ");
}
}
if (isWindows)
{
arg.Append("-hwaccel qsv -init_hw_device qsv=hw ");
arg.Append("-hwaccel qsv ");
}
}
// While using SW decoder
@@ -511,6 +512,12 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
}
if (state.IsVideoRequest
&& string.Equals(encodingOptions.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase))
{
arg.Append("-hwaccel videotoolbox ");
}
}
arg.Append("-i ")
@@ -1599,32 +1606,54 @@ namespace MediaBrowser.Controller.MediaEncoding
{
outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"');
var index = outputSizeParam.IndexOf("hwdownload", StringComparison.OrdinalIgnoreCase);
// hwupload=extra_hw_frames=64,vpp_qsv (for overlay_qsv on linux)
var index = outputSizeParam.IndexOf("hwupload=extra_hw_frames", StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
outputSizeParam = outputSizeParam.Substring(index);
}
else
{
index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase);
// vpp_qsv
index = outputSizeParam.IndexOf("vpp", StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
outputSizeParam = outputSizeParam.Substring(index);
}
else
{
index = outputSizeParam.IndexOf("yadif", StringComparison.OrdinalIgnoreCase);
// hwdownload,format=p010le (hardware decode + software encode for vaapi)
index = outputSizeParam.IndexOf("hwdownload", StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
outputSizeParam = outputSizeParam.Substring(index);
}
else
{
index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase);
// format=nv12|vaapi,hwupload,scale_vaapi
index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
outputSizeParam = outputSizeParam.Substring(index);
}
else
{
// yadif,scale=expr
index = outputSizeParam.IndexOf("yadif", StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
outputSizeParam = outputSizeParam.Substring(index);
}
else
{
// scale=expr
index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
outputSizeParam = outputSizeParam.Substring(index);
}
}
}
}
}
}
@@ -1685,7 +1714,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// If we're hardware VAAPI decoding and software encoding, download frames from the decoder first
else if (IsVaapiSupported(state) && videoDecoder.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1
else if (_mediaEncoder.SupportsHwaccel("vaapi") && videoDecoder.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1
&& string.Equals(outputVideoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
{
/*
@@ -1790,6 +1819,10 @@ namespace MediaBrowser.Controller.MediaEncoding
var outputWidth = width.Value;
var outputHeight = height.Value;
var qsv_or_vaapi = string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase);
var isDeintEnabled = state.DeInterlace("h264", true)
|| state.DeInterlace("avc", true)
|| state.DeInterlace("h265", true)
|| state.DeInterlace("hevc", true);
if (!videoWidth.HasValue
|| outputWidth != videoWidth.Value
@@ -1805,7 +1838,7 @@ namespace MediaBrowser.Controller.MediaEncoding
qsv_or_vaapi ? "vpp_qsv" : "scale_vaapi",
outputWidth,
outputHeight,
(qsv_or_vaapi && state.DeInterlace("h264", true)) ? ":deinterlace=1" : string.Empty));
(qsv_or_vaapi && isDeintEnabled) ? ":deinterlace=1" : string.Empty));
}
else
{
@@ -1814,7 +1847,7 @@ namespace MediaBrowser.Controller.MediaEncoding
CultureInfo.InvariantCulture,
"{0}=format=nv12{1}",
qsv_or_vaapi ? "vpp_qsv" : "scale_vaapi",
(qsv_or_vaapi && state.DeInterlace("h264", true)) ? ":deinterlace=1" : string.Empty));
(qsv_or_vaapi && isDeintEnabled) ? ":deinterlace=1" : string.Empty));
}
}
else if ((videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1
@@ -2026,7 +2059,6 @@ namespace MediaBrowser.Controller.MediaEncoding
// http://sonnati.wordpress.com/2012/10/19/ffmpeg-the-swiss-army-knife-of-internet-streaming-part-vi/
var request = state.BaseRequest;
var videoStream = state.VideoStream;
var filters = new List<string>();
@@ -2035,23 +2067,31 @@ namespace MediaBrowser.Controller.MediaEncoding
var inputHeight = videoStream?.Height;
var threeDFormat = state.MediaSource.Video3DFormat;
var isVaapiDecoder = videoDecoder.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1;
var isVaapiH264Encoder = outputVideoCodec.IndexOf("h264_vaapi", StringComparison.OrdinalIgnoreCase) != -1;
var isQsvH264Encoder = outputVideoCodec.IndexOf("h264_qsv", StringComparison.OrdinalIgnoreCase) != -1;
var isNvdecH264Decoder = videoDecoder.IndexOf("h264_cuvid", StringComparison.OrdinalIgnoreCase) != -1;
var isLibX264Encoder = outputVideoCodec.IndexOf("libx264", StringComparison.OrdinalIgnoreCase) != -1;
var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
// When the input may or may not be hardware VAAPI decodable
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
if (isVaapiH264Encoder)
{
filters.Add("format=nv12|vaapi");
filters.Add("hwupload");
}
// When the input may or may not be hardware QSV decodable
else if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
// When burning in graphical subtitles using overlay_qsv, upload videostream to the same qsv context
else if (isLinux && hasGraphicalSubs && isQsvH264Encoder)
{
filters.Add("format=nv12|qsv");
filters.Add("hwupload=extra_hw_frames=64");
}
// If we're hardware VAAPI decoding and software encoding, download frames from the decoder first
else if (IsVaapiSupported(state) && videoDecoder.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1
&& string.Equals(outputVideoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
else if (IsVaapiSupported(state) && isVaapiDecoder && isLibX264Encoder)
{
var codec = videoStream.Codec.ToLowerInvariant();
var isColorDepth10 = IsColorDepth10(state);
@@ -2079,16 +2119,19 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// Add hardware deinterlace filter before scaling filter
if (state.DeInterlace("h264", true))
if (state.DeInterlace("h264", true) || state.DeInterlace("avc", true))
{
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
if (isVaapiH264Encoder)
{
filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_vaapi"));
}
}
// Add software deinterlace filter before scaling filter
if (state.DeInterlace("h264", true) || state.DeInterlace("h265", true) || state.DeInterlace("hevc", true))
if (state.DeInterlace("h264", true)
|| state.DeInterlace("avc", true)
|| state.DeInterlace("h265", true)
|| state.DeInterlace("hevc", true))
{
var deintParam = string.Empty;
var inputFramerate = videoStream?.RealFrameRate;
@@ -2105,9 +2148,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (!string.IsNullOrEmpty(deintParam))
{
if (!string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)
&& videoDecoder.IndexOf("h264_cuvid", StringComparison.OrdinalIgnoreCase) == -1)
if (!isVaapiH264Encoder && !isQsvH264Encoder && !isNvdecH264Decoder)
{
filters.Add(deintParam);
}
@@ -2117,12 +2158,10 @@ namespace MediaBrowser.Controller.MediaEncoding
// Add scaling filter: scale_*=format=nv12 or scale_*=w=*:h=*:format=nv12 or scale=expr
filters.AddRange(GetScalingFilters(state, inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight));
// Add parameters to use VAAPI with burn-in text subttiles (GH issue #642)
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
// Add parameters to use VAAPI with burn-in text subtitles (GH issue #642)
if (isVaapiH264Encoder)
{
if (state.SubtitleStream != null
&& state.SubtitleStream.IsTextSubtitleStream
&& state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
if (hasTextSubs)
{
// Test passed on Intel and AMD gfx
filters.Add("hwmap=mode=read+write");
@@ -2132,9 +2171,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var output = string.Empty;
if (state.SubtitleStream != null
&& state.SubtitleStream.IsTextSubtitleStream
&& state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
if (hasTextSubs)
{
var subParam = GetTextSubtitleParam(state);
@@ -2142,7 +2179,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// Ensure proper filters are passed to ffmpeg in case of hardware acceleration via VA-API
// Reference: https://trac.ffmpeg.org/wiki/Hardware/VAAPI
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
if (isVaapiH264Encoder)
{
filters.Add("hwmap");
}

View File

@@ -172,7 +172,13 @@ namespace MediaBrowser.MediaEncoding.Subtitles
inputFiles = new[] { mediaSource.Path };
}
var fileInfo = await GetReadableFile(mediaSource.Path, inputFiles, mediaSource.Protocol, subtitleStream, cancellationToken).ConfigureAwait(false);
var protocol = mediaSource.Protocol;
if (subtitleStream.IsExternal)
{
protocol = _mediaSourceManager.GetPathProtocol(subtitleStream.Path);
}
var fileInfo = await GetReadableFile(mediaSource.Path, inputFiles, protocol, subtitleStream, cancellationToken).ConfigureAwait(false);
var stream = await GetSubtitleStream(fileInfo.Path, fileInfo.Protocol, fileInfo.IsExternal, cancellationToken).ConfigureAwait(false);
@@ -426,7 +432,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
// FFmpeg automatically convert character encoding when it is UTF-16
// If we specify character encoding, it rejects with "do not specify a character encoding" and "Unable to recode subtitle event"
if ((inputPath.EndsWith(".smi") || inputPath.EndsWith(".sami")) && (encodingParam == "UTF-16BE" || encodingParam == "UTF-16LE"))
if ((inputPath.EndsWith(".smi") || inputPath.EndsWith(".sami")) &&
(encodingParam.Equals("UTF-16BE", StringComparison.OrdinalIgnoreCase) ||
encodingParam.Equals("UTF-16LE", StringComparison.OrdinalIgnoreCase)))
{
encodingParam = "";
}

View File

@@ -1,3 +1,4 @@
#pragma warning disable CA1819 // Properties should not return arrays
#pragma warning disable CS1591
using System;
@@ -9,21 +10,27 @@ namespace MediaBrowser.Model.Notifications
public NotificationOption(string type)
{
Type = type;
DisabledServices = Array.Empty<string>();
DisabledMonitorUsers = Array.Empty<string>();
SendToUsers = Array.Empty<string>();
}
public string Type { get; set; }
public NotificationOption()
{
DisabledServices = Array.Empty<string>();
DisabledMonitorUsers = Array.Empty<string>();
SendToUsers = Array.Empty<string>();
}
public string? Type { get; set; }
/// <summary>
/// User Ids to not monitor (it's opt out).
/// Gets or sets user Ids to not monitor (it's opt out).
/// </summary>
public string[] DisabledMonitorUsers { get; set; }
/// <summary>
/// User Ids to send to (if SendToUserMode == Custom)
/// Gets or sets user Ids to send to (if SendToUserMode == Custom).
/// </summary>
public string[] SendToUsers { get; set; }

View File

@@ -28,29 +28,31 @@
pluginId: "a629c0da-fac5-4c7e-931a-7174223f14c8"
};
$('.configPage').on('pageshow', function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
$('#enable').checked = config.Enable;
$('#replaceAlbumName').checked = config.ReplaceAlbumName;
Dashboard.hideLoadingMsg();
});
});
$('.configForm').on('submit', function (e) {
Dashboard.showLoadingMsg();
var form = this;
ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
config.Enable = $('#enable', form).checked;
config.ReplaceAlbumName = $('#replaceAlbumName', form).checked;
ApiClient.updatePluginConfiguration(PluginConfig.pluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
document.querySelector('.configPage')
.addEventListener('pageshow', function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
document.querySelector('#enable').checked = config.Enable;
document.querySelector('#replaceAlbumName').checked = config.ReplaceAlbumName;
Dashboard.hideLoadingMsg();
});
});
return false;
});
document.querySelector('.configForm')
.addEventListener('submit', function (e) {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
config.Enable = document.querySelector('#enable').checked;
config.ReplaceAlbumName = document.querySelector('#replaceAlbumName').checked;
ApiClient.updatePluginConfiguration(PluginConfig.pluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
});
e.preventDefault();
return false;
});
</script>
</div>
</body>

View File

@@ -19,6 +19,9 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
public override string Description => "Get artist and album metadata or images from AudioDB.";
// TODO remove when plugin removed from server.
public override string ConfigurationFileName => "Jellyfin.Plugin.AudioDb.xml";
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
: base(applicationPaths, xmlSerializer)
{

View File

@@ -36,33 +36,47 @@
uniquePluginId: "8c95c4d2-e50c-4fb0-a4f3-6c06ff0f9a1a"
};
$('.musicBrainzConfigPage').on('pageshow', function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(MusicBrainzPluginConfig.uniquePluginId).then(function (config) {
$('#server').val(config.Server).change();
$('#rateLimit').val(config.RateLimit).change();
$('#enable').checked = config.Enable;
$('#replaceArtistName').checked = config.ReplaceArtistName;
document.querySelector('.musicBrainzConfigPage')
.addEventListener('pageshow', function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(MusicBrainzPluginConfig.uniquePluginId).then(function (config) {
var server = document.querySelector('#server');
server.value = config.Server;
server.dispatchEvent(new Event('change', {
bubbles: true,
cancelable: false
}));
var rateLimit = document.querySelector('#rateLimit');
rateLimit.value = config.RateLimit;
rateLimit.dispatchEvent(new Event('change', {
bubbles: true,
cancelable: false
}));
document.querySelector('#enable').checked = config.Enable;
document.querySelector('#replaceArtistName').checked = config.ReplaceArtistName;
Dashboard.hideLoadingMsg();
Dashboard.hideLoadingMsg();
});
});
});
$('.musicBrainzConfigForm').on('submit', function (e) {
Dashboard.showLoadingMsg();
var form = this;
ApiClient.getPluginConfiguration(MusicBrainzPluginConfig.uniquePluginId).then(function (config) {
config.Server = $('#server', form).val();
config.RateLimit = $('#rateLimit', form).val();
config.Enable = $('#enable', form).checked;
config.ReplaceArtistName = $('#replaceArtistName', form).checked;
ApiClient.updatePluginConfiguration(MusicBrainzPluginConfig.uniquePluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
document.querySelector('.musicBrainzConfigForm')
.addEventListener('submit', function (e) {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(MusicBrainzPluginConfig.uniquePluginId).then(function (config) {
config.Server = document.querySelector('#server').value;
config.RateLimit = document.querySelector('#rateLimit').value;
config.Enable = document.querySelector('#enable').checked;
config.ReplaceArtistName = document.querySelector('#replaceArtistName').checked;
ApiClient.updatePluginConfiguration(MusicBrainzPluginConfig.uniquePluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
});
e.preventDefault();
return false;
});
return false;
});
</script>
</div>
</body>

View File

@@ -23,6 +23,9 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz
public const long DefaultRateLimit = 2000u;
// TODO remove when plugin removed from server.
public override string ConfigurationFileName => "Jellyfin.Plugin.MusicBrainz.xml";
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
: base(applicationPaths, xmlSerializer)
{

View File

@@ -24,25 +24,28 @@
pluginId: "a628c0da-fac5-4c7e-9d1a-7134223f14c8"
};
$('.configPage').on('pageshow', function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
$('#castAndCrew').checked = config.CastAndCrew;
Dashboard.hideLoadingMsg();
});
});
$('.configForm').on('submit', function (e) {
Dashboard.showLoadingMsg();
var form = this;
ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
config.CastAndCrew = $('#castAndCrew', form).checked;
ApiClient.updatePluginConfiguration(PluginConfig.pluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
document.querySelector('.configPage')
.addEventListener('pageshow', function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
document.querySelector('#castAndCrew').checked = config.CastAndCrew;
Dashboard.hideLoadingMsg();
});
});
return false;
});
document.querySelector('.configForm')
.addEventListener('submit', function (e) {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
config.CastAndCrew = document.querySelector('#castAndCrew').checked;
ApiClient.updatePluginConfiguration(PluginConfig.pluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
});
e.preventDefault();
return false;
});
</script>
</div>
</body>

View File

@@ -19,6 +19,9 @@ namespace MediaBrowser.Providers.Plugins.Omdb
public override string Description => "Get metadata for movies and other video content from OMDb.";
// TODO remove when plugin removed from server.
public override string ConfigurationFileName => "Jellyfin.Plugin.Omdb.xml";
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
: base(applicationPaths, xmlSerializer)
{

View File

@@ -17,6 +17,9 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
public override string Description => "Get metadata for movies and other video content from TheTVDB.";
// TODO remove when plugin removed from server.
public override string ConfigurationFileName => "Jellyfin.Plugin.TheTvdb.xml";
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
: base(applicationPaths, xmlSerializer)
{

View File

@@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
public BelongsToCollection Belongs_To_Collection { get; set; }
public int Budget { get; set; }
public long Budget { get; set; }
public List<Genre> Genres { get; set; }
@@ -39,7 +39,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
public string Release_Date { get; set; }
public int Revenue { get; set; }
public long Revenue { get; set; }
public int Runtime { get; set; }

View File

@@ -1,4 +1,4 @@
using System.Reflection;
[assembly: AssemblyVersion("10.6.0")]
[assembly: AssemblyFileVersion("10.6.0")]
[assembly: AssemblyVersion("10.6.4")]
[assembly: AssemblyFileVersion("10.6.4")]

View File

@@ -1,7 +1,7 @@
---
# We just wrap `build` so this is really it
name: "jellyfin"
version: "10.6.0"
version: "10.6.4"
packages:
- debian.amd64
- debian.arm64

View File

@@ -4,6 +4,7 @@
set -o errexit
set -o pipefail
set -o xtrace
usage() {
echo -e "bump_version - increase the shared version and generate changelogs"
@@ -58,7 +59,7 @@ sed -i "s/${old_version_sed}/${new_version}/g" ${debian_equivs_file}
debian_changelog_file="debian/changelog"
debian_changelog_temp="$( mktemp )"
# Create new temp file with our changelog
echo -e "jellyfin (${new_version_deb}) unstable; urgency=medium
echo -e "jellyfin-server (${new_version_deb}) unstable; urgency=medium
* New upstream version ${new_version}; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v${new_version}

30
debian/changelog vendored
View File

@@ -1,3 +1,33 @@
jellyfin-server (10.6.4-1) unstable; urgency=medium
* New upstream version 10.6.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.6.4
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 30 Aug 2020 16:44:45 -0400
jellyfin-server (10.6.3-1) unstable; urgency=medium
* New upstream version 10.6.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.6.3
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 16 Aug 2020 20:19:52 -0400
jellyfin-server (10.6.2-1) unstable; urgency=medium
* New upstream version 10.6.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.6.2
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 02 Aug 2020 20:53:02 -0400
jellyfin-server (10.6.1-1) unstable; urgency=medium
* New upstream version 10.6.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.6.1
-- Jellyfin Packaging Team <packaging@jellyfin.org> Mon, 27 Jul 2020 18:59:03 -0400
jellyfin-server (10.6.0-2) unstable; urgency=medium
* Fix upgrade bug
-- Joshua Boniface <joshua@boniface.me> Sun, 19 Jul 22:47:27 -0400
jellyfin-server (10.6.0-1) unstable; urgency=medium
* Forthcoming stable release

View File

@@ -31,7 +31,7 @@ JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/lib/jellyfin-ffmpeg/ffmpeg"
#JELLYFIN_SERVICE_OPT="--service"
# [OPTIONAL] run Jellyfin without the web app
#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp"
#JELLYFIN_NOWEBAPP_OPT="--nowebclient"
#
# SysV init/Upstart options
@@ -40,4 +40,4 @@ JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/lib/jellyfin-ffmpeg/ffmpeg"
# Application username
JELLYFIN_USER="jellyfin"
# Full application command
JELLYFIN_ARGS="$JELLYFIN_WEB_OPT $JELLYFIN_RESTART_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT $JELLFIN_NOWEBAPP_OPT"
JELLYFIN_ARGS="$JELLYFIN_WEB_OPT $JELLYFIN_RESTART_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT $JELLYFIN_NOWEBAPP_OPT"

5
debian/control vendored
View File

@@ -15,9 +15,8 @@ Vcs-Git: https://github.org/jellyfin/jellyfin.git
Vcs-Browser: https://github.org/jellyfin/jellyfin
Package: jellyfin-server
Replaces: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server
Breaks: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server
Conflicts: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server
Replaces: jellyfin (<<10.6.0)
Breaks: jellyfin (<<10.6.0)
Architecture: any
Depends: at,
libsqlite3-0,

View File

@@ -5,7 +5,7 @@ Homepage: https://jellyfin.org
Standards-Version: 3.9.2
Package: jellyfin
Version: 10.6.0
Version: 10.6.4
Maintainer: Jellyfin Packaging Team <packaging@jellyfin.org>
Depends: jellyfin-server, jellyfin-web
Description: Provides the Jellyfin Free Software Media System

View File

@@ -16,7 +16,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -15,7 +15,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -16,7 +16,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -15,7 +15,7 @@ RUN apt-get update \
# Install dotnet repository
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
RUN wget https://download.visualstudio.microsoft.com/download/pr/c1a30ceb-adc2-4244-b24a-06ca29bb1ee9/6df5d856ff1b3e910d283f89690b7cae/dotnet-sdk-3.1.302-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet

View File

@@ -7,7 +7,7 @@
%endif
Name: jellyfin
Version: 10.6.0
Version: 10.6.4
Release: 1%{?dist}
Summary: The Free Software Media System
License: GPLv3
@@ -74,6 +74,9 @@ EOF
%{__install} -D -m 0755 %{SOURCE14} %{buildroot}%{_libexecdir}/jellyfin/restart.sh
%{__install} -D -m 0644 %{SOURCE16} %{buildroot}%{_prefix}/lib/firewalld/services/jellyfin.xml
%files
# empty as this is just a meta-package
%files server
%attr(755,root,root) %{_bindir}/jellyfin
%{_libdir}/jellyfin/*.json
@@ -139,6 +142,14 @@ fi
%systemd_postun_with_restart jellyfin.service
%changelog
* Sun Aug 30 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.6.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.6.4
* Sun Aug 16 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.6.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.6.3
* Sun Aug 02 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.6.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.6.2
* Mon Jul 27 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.6.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.6.1
* Mon Mar 23 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
- Forthcoming stable release
* Fri Oct 11 2019 Jellyfin Packaging Team <packaging@jellyfin.org>

View File

@@ -9,17 +9,28 @@ namespace Jellyfin.Server.Implementations.Tests.Library
[InlineData("/media/small.jpg", true)]
[InlineData("/media/albumart.jpg", true)]
[InlineData("/media/movie.sample.mp4", true)]
[InlineData("/media/movie/sample.mp4", true)]
[InlineData("/media/movie/sample/movie.mp4", true)]
[InlineData("/foo/sample/bar/baz.mkv", false)]
[InlineData("/media/movies/the sample/the sample.mkv", false)]
[InlineData("/media/movies/sampler.mkv", false)]
[InlineData("/media/movies/#Recycle/test.txt", true)]
[InlineData("/media/movies/#recycle/", true)]
[InlineData("/media/movies/#recycle", true)]
[InlineData("thumbs.db", true)]
[InlineData(@"C:\media\movies\movie.avi", false)]
[InlineData("/media/.hiddendir/file.mp4", true)]
[InlineData("/media/.hiddendir/file.mp4", false)]
[InlineData("/media/dir/.hiddenfile.mp4", true)]
[InlineData("/media/dir/._macjunk.mp4", true)]
[InlineData("/volume1/video/Series/@eaDir", true)]
[InlineData("/volume1/video/Series/@eaDir/file.txt", true)]
[InlineData("/directory/@Recycle", true)]
[InlineData("/directory/@Recycle/file.mp3", true)]
[InlineData("/media/movies/.@__thumb", true)]
[InlineData("/media/movies/.@__thumb/foo-bar-thumbnail.png", true)]
[InlineData("/media/music/Foo B.A.R./epic.flac", false)]
[InlineData("/media/music/Foo B.A.R", false)]
[InlineData("/media/music/Foo B.A.R.", false)]
public void PathIgnored(string path, bool expected)
{
Assert.Equal(expected, IgnorePatterns.ShouldIgnore(path));