Compare commits

...

31 Commits

Author SHA1 Message Date
Joshua M. Boniface
d5fe82314e Bump version for 10.3.5 2019-06-09 21:47:45 -04:00
Joshua M. Boniface
06834fefef Merge pull request #1447 from joshuaboniface/implement-invalidauth
Implement InvalidAuthProvider
2019-06-09 15:36:25 -04:00
Joshua M. Boniface
2946ae1009 Revert "Don't set a default reset provider"
This reverts commit c230d49d7c.

This reenables an edge case where an admin might want to reset, with
the default auth provider, the password of an externally-provided
user so they could "unlock" the account while it was failing. There
might be minor security implications to this, but the malicious
actor would need FS access to do it (as they would with any password
resets) so it's probably best to keep it as-is.

Removing this in the first place was due to a misunderstanding
anyways so no harm.
2019-06-09 15:29:43 -04:00
Joshua M. Boniface
4b8f735cb8 Remove superfluous conditional
This wasn't needed to prevent updating the policy on-disk from my
tests and can be removed as suggested by @Bond-009
2019-06-09 13:57:49 -04:00
Joshua M. Boniface
c230d49d7c Don't set a default reset provider 2019-06-09 13:46:53 -04:00
Joshua M. Boniface
20e2cb2d86 Use SecurityException for auth failure 2019-06-09 13:45:51 -04:00
Joshua M. Boniface
b70083f3b3 Apply suggestions from code review
Co-Authored-By: Claus Vium <cvium@users.noreply.github.com>
Co-Authored-By: Bond-009 <bond.009@outlook.com>
2019-06-09 13:41:14 -04:00
Joshua M. Boniface
74ef389879 Add nicer log message and comment 2019-06-09 11:07:35 -04:00
Joshua M. Boniface
d78a55adb4 Implement InvalidAuthProvider
Implements the InvalidAuthProvider, which acts as a fallback if a
configured authentication provider, e.g. LDAP, is unavailable due
to a load failure or removal. Until the user or the authentication
plugin is corrected, this will cause users with the missing provider
to be locked out, while throwing errors in the logs about the issue.

Fixes #1445 part 2
2019-06-08 22:54:31 -04:00
Andrew Rabert
6f99ed3955 Merge pull request #1443 from jellyfin/qemu
Docker - Update arm* Dockerfiles for latest multiarch
2019-06-07 18:41:35 -04:00
Andrew Rabert
247a5e12ab Docker - Update arm* Dockerfiles for latest multiarch
Relates to this change 7bdafb96ee
2019-06-07 00:00:14 -04:00
Joshua M. Boniface
855911333a Bump version for 10.3.4 2019-06-06 22:45:37 -04:00
Anthony Lavado
127bfc7d3b Merge pull request #1437 from pjeanjean/master
Fix issue #1436: media folders appear empty unless user has all libraries access
2019-06-06 17:21:20 -04:00
pjeanjean
7919dd81da Skip user permission checking for UserRootFolder
Fix #1436
UserRootFolders are used to represent virtual folders that exist outside
of libraries. As such, it doesn't make sense to check if a user has the
right to access their library (named `Media Folders`).
2019-06-06 08:30:56 +02:00
Anthony Lavado
e1da046960 Merge pull request #1426 from jellyfin/cvium-fix-tvdb-refresh
Fix inverted comparison in the tvdb token refresh logic
2019-05-31 21:27:33 -04:00
Claus Vium
a756026962 Fix inverted comparison in the tvdb token refresh logic 2019-05-31 07:24:52 +02:00
Anthony Lavado
75260a960b Merge pull request #1406 from DrPandemic/fix-pin-update
Format the PIN when updating it
2019-05-31 00:58:53 -04:00
DrPandemic
69ee49bee6 Format correctly the PIN when updating it 2019-05-25 13:46:55 -04:00
Joshua M. Boniface
1bf3a26a61 Bump version for 10.3.3 2019-05-17 23:12:21 -04:00
Joshua M. Boniface
c5760b3a40 Merge pull request #1380 from bugfixin/dlna-photo-thumb-fix
Improve Photo rendering in DLNA
2019-05-17 22:55:43 -04:00
Joshua M. Boniface
4de8bf3295 Merge pull request #1338 from cvium/fix_extras
Enforce a specific folder structure for Extras to avoid misidentification
2019-05-17 09:00:22 -04:00
bugfixin
87c8f19f19 Move DLNA thumbnail element to after larger image elements 2019-05-16 18:00:38 +00:00
Claus Vium
0ef52c739e Review changes
Untested
2019-05-16 07:27:38 +02:00
Joshua M. Boniface
0a9a6b949c Merge pull request #1372 from DrPandemic/fix-pin
Fix broken pin in 10.3.z
2019-05-14 21:54:28 -04:00
DrPandemic
c22068d6b1 Fix pin bug introduced in 10.3.z.
The issue is that the new easyPassword format prepends the hash
function. This PR extract the hash from "$SHA1$_hash_".
2019-05-11 19:53:34 -04:00
Joshua M. Boniface
bbc1a86b57 Merge pull request #1306 from oddstr13/pr-sudoless-build-1
Move artifact chown inside docker to avoid sudo
2019-05-10 09:25:41 -04:00
Bond-009
cd83d80f2b Merge pull request #1294 from DrPandemic/fix-download-non-ascii
Fix non-ascii filename downloads
2019-05-09 17:30:19 +02:00
Jean-Samuel Aubry-Guzzi
12721eb7dd Fix non-ascii filename downloads
Follow https://tools.ietf.org/html/rfc5987#section-3.2.2 to encode
non-ascii filenames in HTTP Content-Disposition header.
2019-05-07 19:43:04 -04:00
Claus Vium
b8a09339cd Enforce extras folder structure according to Emby's wiki 2019-05-02 08:14:00 +02:00
Odd Stråbø
3634d367c1 Move artifact chown inside docker to avoid sudo 2019-05-01 20:32:15 +02:00
Claus Vium
c1daea0ec7 Change owner and parent id of extras to the main media item 2019-05-01 07:47:22 +02:00
34 changed files with 232 additions and 107 deletions

View File

@@ -24,6 +24,7 @@
- [Lynxy](https://github.com/Lynxy)
- [fasheng](https://github.com/fasheng)
- [ploughpuff](https://github.com/ploughpuff)
- [pjeanjean](https://github.com/pjeanjean)
# Emby Contributors

View File

@@ -21,7 +21,7 @@ RUN apt-get update \
COPY --from=ffmpeg / /
COPY --from=builder /jellyfin /jellyfin
ARG JELLYFIN_WEB_VERSION=10.3.2
ARG JELLYFIN_WEB_VERSION=10.3.5
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web

View File

@@ -3,11 +3,6 @@
ARG DOTNET_VERSION=3.0
FROM multiarch/qemu-user-static:x86_64-arm as qemu
FROM alpine as qemu_extract
COPY --from=qemu /usr/bin qemu-arm-static.tar.gz
RUN tar -xzvf qemu-arm-static.tar.gz
FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
@@ -21,8 +16,9 @@ RUN bash -c "source deployment/common.build.sh && \
build_jellyfin Jellyfin.Server Release linux-arm /jellyfin"
FROM multiarch/qemu-user-static:x86_64-arm as qemu
FROM mcr.microsoft.com/dotnet/core/runtime:${DOTNET_VERSION}-stretch-slim-arm32v7
COPY --from=qemu_extract qemu-arm-static /usr/bin
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
&& rm -rf /var/lib/apt/lists/* \
@@ -30,7 +26,7 @@ RUN apt-get update \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
ARG JELLYFIN_WEB_VERSION=10.3.2
ARG JELLYFIN_WEB_VERSION=10.3.5
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web

View File

@@ -3,12 +3,6 @@
ARG DOTNET_VERSION=3.0
FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu
FROM alpine as qemu_extract
COPY --from=qemu /usr/bin qemu-aarch64-static.tar.gz
RUN tar -xzvf qemu-aarch64-static.tar.gz
FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
@@ -22,8 +16,9 @@ RUN bash -c "source deployment/common.build.sh && \
build_jellyfin Jellyfin.Server Release linux-arm64 /jellyfin"
FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu
FROM mcr.microsoft.com/dotnet/core/runtime:${DOTNET_VERSION}-stretch-slim-arm64v8
COPY --from=qemu_extract qemu-aarch64-static /usr/bin
COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
&& rm -rf /var/lib/apt/lists/* \
@@ -31,7 +26,7 @@ RUN apt-get update \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
ARG JELLYFIN_WEB_VERSION=10.3.2
ARG JELLYFIN_WEB_VERSION=10.3.5
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web

View File

@@ -920,8 +920,6 @@ namespace Emby.Dlna.Didl
}
}
AddImageResElement(item, writer, 160, 160, "jpg", "JPEG_TN");
if (!_profile.EnableSingleAlbumArtLimit || string.Equals(item.MediaType, MediaType.Photo, StringComparison.OrdinalIgnoreCase))
{
AddImageResElement(item, writer, 4096, 4096, "jpg", "JPEG_LRG");
@@ -930,6 +928,9 @@ namespace Emby.Dlna.Didl
AddImageResElement(item, writer, 4096, 4096, "png", "PNG_LRG");
AddImageResElement(item, writer, 160, 160, "png", "PNG_TN");
}
AddImageResElement(item, writer, 160, 160, "jpg", "JPEG_TN");
}
private void AddEmbeddedImageAsCover(string name, XmlWriter writer)

View File

@@ -19,7 +19,7 @@ namespace Emby.Server.Implementations.Library
public string Name => "Default";
public bool IsEnabled => true;
// This is dumb and an artifact of the backwards way auth providers were designed.
// This version of authenticate was never meant to be called, but needs to be here for interface compat
// Only the providers that don't provide local user support use this
@@ -27,7 +27,7 @@ namespace Emby.Server.Implementations.Library
{
throw new NotImplementedException();
}
// This is the verson that we need to use for local users. Because reasons.
public Task<ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser)
{
@@ -103,7 +103,7 @@ namespace Emby.Server.Implementations.Library
string hash = user.Password;
user.Password = string.Format("$SHA1${0}", hash);
}
if (user.EasyPassword != null && !user.EasyPassword.Contains("$"))
{
string hash = user.EasyPassword;
@@ -165,6 +165,34 @@ namespace Emby.Server.Implementations.Library
return user.Password;
}
public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash)
{
ConvertPasswordFormat(user);
if (newPassword != null)
{
newPasswordHash = string.Format("$SHA1${0}", GetHashedString(user, newPassword));
}
if (string.IsNullOrWhiteSpace(newPasswordHash))
{
throw new ArgumentNullException(nameof(newPasswordHash));
}
user.EasyPassword = newPasswordHash;
}
public string GetEasyPasswordHash(User user)
{
// This should be removed in the future. This was added to let user login after
// Jellyfin 10.3.3 failed to save a well formatted PIN.
ConvertPasswordFormat(user);
return string.IsNullOrEmpty(user.EasyPassword)
? null
: (new PasswordHash(user.EasyPassword)).Hash;
}
public string GetHashedStringChangeAuth(string newPassword, PasswordHash passwordHash)
{
passwordHash.HashBytes = Encoding.UTF8.GetBytes(newPassword);

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Net;
namespace Emby.Server.Implementations.Library
{
public class InvalidAuthProvider : IAuthenticationProvider
{
public string Name => "InvalidOrMissingAuthenticationProvider";
public bool IsEnabled => true;
public Task<ProviderAuthenticationResult> Authenticate(string username, string password)
{
throw new SecurityException("User Account cannot login with this provider. The Normal provider for this user cannot be found");
}
public Task<bool> HasPassword(User user)
{
return Task.FromResult(true);
}
public Task ChangePassword(User user, string newPassword)
{
return Task.CompletedTask;
}
public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash)
{
// Nothing here
}
public string GetPasswordHash(User user)
{
return string.Empty;
}
public string GetEasyPasswordHash(User user)
{
return string.Empty;
}
}
}

View File

@@ -79,6 +79,8 @@ namespace Emby.Server.Implementations.Library
private IAuthenticationProvider[] _authenticationProviders;
private DefaultAuthenticationProvider _defaultAuthenticationProvider;
private InvalidAuthProvider _invalidAuthProvider;
private IPasswordResetProvider[] _passwordResetProviders;
private DefaultPasswordResetProvider _defaultPasswordResetProvider;
@@ -141,6 +143,8 @@ namespace Emby.Server.Implementations.Library
_defaultAuthenticationProvider = _authenticationProviders.OfType<DefaultAuthenticationProvider>().First();
_invalidAuthProvider = _authenticationProviders.OfType<InvalidAuthProvider>().First();
_passwordResetProviders = passwordResetProviders.ToArray();
_defaultPasswordResetProvider = passwordResetProviders.OfType<DefaultPasswordResetProvider>().First();
@@ -307,8 +311,7 @@ namespace Emby.Server.Implementations.Library
user = Users
.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
var hasNewUserPolicy = authenticationProvider as IHasNewUserPolicy;
if (hasNewUserPolicy != null)
if (authenticationProvider is IHasNewUserPolicy hasNewUserPolicy)
{
var policy = hasNewUserPolicy.GetNewUserPolicy();
UpdateUserPolicy(user, policy, true);
@@ -400,7 +403,9 @@ namespace Emby.Server.Implementations.Library
if (providers.Length == 0)
{
providers = new IAuthenticationProvider[] { _defaultAuthenticationProvider };
// Assign the user to the InvalidAuthProvider since no configured auth provider was valid/found
_logger.LogWarning("User {UserName} was found with invalid/missing Authentication Provider {AuthenticationProviderId}. Assigning user to InvalidAuthProvider until this is corrected", user.Name, user.Policy.AuthenticationProviderId);
providers = new IAuthenticationProvider[] { _invalidAuthProvider };
}
return providers;
@@ -471,7 +476,7 @@ namespace Emby.Server.Implementations.Library
if (password == null)
{
// legacy
success = string.Equals(_defaultAuthenticationProvider.GetPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
success = string.Equals(GetAuthenticationProvider(user).GetPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
}
else
{
@@ -497,11 +502,11 @@ namespace Emby.Server.Implementations.Library
if (password == null)
{
// legacy
success = string.Equals(GetLocalPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
success = string.Equals(GetAuthenticationProvider(user).GetEasyPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
}
else
{
success = string.Equals(GetLocalPasswordHash(user), _defaultAuthenticationProvider.GetHashedString(user, password), StringComparison.OrdinalIgnoreCase);
success = string.Equals(GetAuthenticationProvider(user).GetEasyPasswordHash(user), _defaultAuthenticationProvider.GetHashedString(user, password), StringComparison.OrdinalIgnoreCase);
}
}
}
@@ -546,13 +551,6 @@ namespace Emby.Server.Implementations.Library
}
}
private string GetLocalPasswordHash(User user)
{
return string.IsNullOrEmpty(user.EasyPassword)
? null
: user.EasyPassword;
}
/// <summary>
/// Loads the users from the repository
/// </summary>
@@ -596,7 +594,7 @@ namespace Emby.Server.Implementations.Library
}
bool hasConfiguredPassword = GetAuthenticationProvider(user).HasPassword(user).Result;
bool hasConfiguredEasyPassword = !string.IsNullOrEmpty(GetLocalPasswordHash(user));
bool hasConfiguredEasyPassword = !string.IsNullOrEmpty(GetAuthenticationProvider(user).GetEasyPasswordHash(user));
bool hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ?
hasConfiguredEasyPassword :
@@ -884,17 +882,7 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentNullException(nameof(user));
}
if (newPassword != null)
{
newPasswordHash = _defaultAuthenticationProvider.GetHashedString(user, newPassword);
}
if (string.IsNullOrWhiteSpace(newPasswordHash))
{
throw new ArgumentNullException(nameof(newPasswordHash));
}
user.EasyPassword = newPasswordHash;
GetAuthenticationProvider(user).ChangeEasyPassword(user, newPassword, newPasswordHash);
UpdateUser(user);

View File

@@ -2,6 +2,8 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Api.Movies;
@@ -828,7 +830,16 @@ namespace MediaBrowser.Api.Library
var filename = (Path.GetFileName(path) ?? string.Empty).Replace("\"", string.Empty);
if (!string.IsNullOrWhiteSpace(filename))
{
headers[HeaderNames.ContentDisposition] = "attachment; filename=\"" + filename + "\"";
// Kestrel doesn't support non-ASCII characters in headers
if (Regex.IsMatch(filename, "[^[:ascii:]]"))
{
// Manually encoding non-ASCII characters, following https://tools.ietf.org/html/rfc5987#section-3.2.2
headers[HeaderNames.ContentDisposition] = "attachment; filename*=UTF-8''" + WebUtility.UrlEncode(filename);
}
else
{
headers[HeaderNames.ContentDisposition] = "attachment; filename=\"" + filename + "\"";
}
}
return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions

View File

@@ -224,7 +224,7 @@ namespace MediaBrowser.Api.UserLibrary
request.IncludeItemTypes = "Playlist";
}
if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Any(i => new Guid(i) == item.Id))
if (!(item is UserRootFolder) && !user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Any(i => new Guid(i) == item.Id))
{
Logger.LogWarning("{UserName} is not permitted to access Library {ItemName}.", user.Name, item.Name);
return new QueryResult<BaseItem>

View File

@@ -11,6 +11,9 @@ namespace MediaBrowser.Controller.Authentication
Task<ProviderAuthenticationResult> Authenticate(string username, string password);
Task<bool> HasPassword(User user);
Task ChangePassword(User user, string newPassword);
void ChangeEasyPassword(User user, string newPassword, string newPasswordHash);
string GetPasswordHash(User user);
string GetEasyPasswordHash(User user);
}
public interface IRequiresResolvedUser

View File

@@ -78,10 +78,25 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// The trailer folder name
/// </summary>
public static string TrailerFolderName = "trailers";
public static string ThemeSongsFolderName = "theme-music";
public static string ThemeSongFilename = "theme";
public static string ThemeVideosFolderName = "backdrops";
public const string TrailerFolderName = "trailers";
public const string ThemeSongsFolderName = "theme-music";
public const string ThemeSongFilename = "theme";
public const string ThemeVideosFolderName = "backdrops";
public const string ExtrasFolderName = "extras";
public const string BehindTheScenesFolderName = "behind the scenes";
public const string DeletedScenesFolderName = "deleted scenes";
public const string InterviewFolderName = "interviews";
public const string SceneFolderName = "scenes";
public const string SampleFolderName = "samples";
public static readonly string[] AllExtrasTypesFolderNames = {
ExtrasFolderName,
BehindTheScenesFolderName,
DeletedScenesFolderName,
InterviewFolderName,
SceneFolderName,
SampleFolderName
};
[IgnoreDataMember]
public Guid[] ThemeSongIds { get; set; }
@@ -1276,16 +1291,15 @@ namespace MediaBrowser.Controller.Entities
.Select(item =>
{
// Try to retrieve it from the db. If we don't find it, use the resolved version
var dbItem = LibraryManager.GetItemById(item.Id) as Video;
if (dbItem != null)
if (LibraryManager.GetItemById(item.Id) is Video dbItem)
{
item = dbItem;
}
else
{
// item is new
item.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo;
item.ExtraType = Model.Entities.ExtraType.ThemeVideo;
}
return item;
@@ -1296,33 +1310,38 @@ namespace MediaBrowser.Controller.Entities
protected virtual BaseItem[] LoadExtras(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{
var files = fileSystemChildren.Where(i => i.IsDirectory)
.SelectMany(i => FileSystem.GetFiles(i.FullName));
var extras = new List<Video>();
return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions())
.OfType<Video>()
.Select(item =>
{
// Try to retrieve it from the db. If we don't find it, use the resolved version
var dbItem = LibraryManager.GetItemById(item.Id) as Video;
var folders = fileSystemChildren.Where(i => i.IsDirectory).ToArray();
foreach (var extraFolderName in AllExtrasTypesFolderNames)
{
var files = folders
.Where(i => string.Equals(i.Name, extraFolderName, StringComparison.OrdinalIgnoreCase))
.SelectMany(i => FileSystem.GetFiles(i.FullName));
if (dbItem != null)
extras.AddRange(LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions())
.OfType<Video>()
.Select(item =>
{
item = dbItem;
}
else
{
// item is new
item.ExtraType = MediaBrowser.Model.Entities.ExtraType.Clip;
}
// Try to retrieve it from the db. If we don't find it, use the resolved version
if (LibraryManager.GetItemById(item.Id) is Video dbItem)
{
item = dbItem;
}
return item;
// Use some hackery to get the extra type based on foldername
Enum.TryParse(extraFolderName.Replace(" ", ""), true, out ExtraType extraType);
item.ExtraType = extraType;
// Sort them so that the list can be easily compared for changes
}).OrderBy(i => i.Path).ToArray();
return item;
// Sort them so that the list can be easily compared for changes
}).OrderBy(i => i.Path));
}
return extras.ToArray();
}
public Task RefreshMetadata(CancellationToken cancellationToken)
{
return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem)), cancellationToken);
@@ -1481,7 +1500,13 @@ namespace MediaBrowser.Controller.Entities
private async Task<bool> RefreshExtras(BaseItem item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newExtras = LoadExtras(fileSystemChildren, options.DirectoryService).Concat(LoadThemeVideos(fileSystemChildren, options.DirectoryService)).Concat(LoadThemeSongs(fileSystemChildren, options.DirectoryService));
var extras = LoadExtras(fileSystemChildren, options.DirectoryService);
var themeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService);
var themeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService);
var newExtras = new BaseItem[extras.Length + themeVideos.Length + themeSongs.Length];
extras.CopyTo(newExtras, 0);
themeVideos.CopyTo(newExtras, extras.Length);
themeSongs.CopyTo(newExtras, extras.Length + themeVideos.Length);
var newExtraIds = newExtras.Select(i => i.Id).ToArray();
@@ -1493,7 +1518,15 @@ namespace MediaBrowser.Controller.Entities
var tasks = newExtras.Select(i =>
{
return RefreshMetadataForOwnedItem(i, true, new MetadataRefreshOptions(options), cancellationToken);
var subOptions = new MetadataRefreshOptions(options);
if (i.OwnerId != ownerId || i.ParentId != Guid.Empty)
{
i.OwnerId = ownerId;
i.ParentId = Guid.Empty;
subOptions.ForceSave = true;
}
return RefreshMetadataForOwnedItem(i, true, subOptions, cancellationToken);
});
await Task.WhenAll(tasks).ConfigureAwait(false);

View File

@@ -33,7 +33,7 @@ namespace MediaBrowser.Providers.TV.TheTVDB
get
{
// Refresh if necessary
if (_tokenCreatedAt > DateTime.Now.Subtract(TimeSpan.FromHours(20)))
if (_tokenCreatedAt < DateTime.Now.Subtract(TimeSpan.FromHours(20)))
{
try
{

View File

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

View File

@@ -1,7 +1,7 @@
---
# We just wrap `build` so this is really it
name: "jellyfin"
version: "10.3.2"
version: "10.3.5"
packages:
- debian-package-x64
- debian-package-armhf

View File

@@ -18,3 +18,4 @@ rpmbuild -bb SPECS/jellyfin.spec --define "_sourcedir ${SOURCE_DIR}/SOURCES/pkg-
# Move the artifacts out
mkdir -p ${ARTIFACT_DIR}/rpm
mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/rpm/
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}

View File

@@ -72,9 +72,6 @@ fi
${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile
# Build the RPMs and copy out to ${package_temporary_dir}
${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}"
# Correct ownership on the RPMs (as current user, then as root if that fails)
chown -R "${current_user}" "${package_temporary_dir}" \
|| sudo chown -R "${current_user}" "${package_temporary_dir}"
# Move the RPMs to the output directory
mkdir -p "${output_dir}"
mv "${package_temporary_dir}"/rpm/* "${output_dir}"

View File

@@ -18,3 +18,4 @@ dpkg-buildpackage -us -uc -aarm64
# Move the artifacts out
mkdir -p ${ARTIFACT_DIR}/deb
mv /jellyfin_* ${ARTIFACT_DIR}/deb/
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}

View File

@@ -30,13 +30,12 @@ case $ARCH in
;;
esac
# Prepare temporary package dir
mkdir -p "${package_temporary_dir}"
# Set up the build environment Docker image
${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE}
# Build the DEBs and copy out to ${package_temporary_dir}
${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}"
# Correct ownership on the DEBs (as current user, then as root if that fails)
chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null \
|| sudo chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null
# Move the DEBs to the output directory
mkdir -p "${output_dir}"
mv "${package_temporary_dir}"/deb/* "${output_dir}"

View File

@@ -18,3 +18,4 @@ dpkg-buildpackage -us -uc -aarmhf
# Move the artifacts out
mkdir -p ${ARTIFACT_DIR}/deb
mv /jellyfin_* ${ARTIFACT_DIR}/deb/
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}

View File

@@ -30,13 +30,12 @@ case $ARCH in
;;
esac
# Prepare temporary package dir
mkdir -p "${package_temporary_dir}"
# Set up the build environment Docker image
${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE}
# Build the DEBs and copy out to ${package_temporary_dir}
${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}"
# Correct ownership on the DEBs (as current user, then as root if that fails)
chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null \
|| sudo chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null
# Move the DEBs to the output directory
mkdir -p "${output_dir}"
mv "${package_temporary_dir}"/deb/* "${output_dir}"

View File

@@ -17,3 +17,4 @@ dpkg-buildpackage -us -uc
# Move the artifacts out
mkdir -p ${ARTIFACT_DIR}/deb
mv /jellyfin_* ${ARTIFACT_DIR}/deb/
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}

View File

@@ -19,13 +19,12 @@ else
docker_sudo=""
fi
# Prepare temporary package dir
mkdir -p "${package_temporary_dir}"
# Set up the build environment Docker image
${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile
# Build the DEBs and copy out to ${package_temporary_dir}
${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}"
# Correct ownership on the DEBs (as current user, then as root if that fails)
chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null \
|| sudo chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null
# Move the DEBs to the output directory
mkdir -p "${output_dir}"
mv "${package_temporary_dir}"/deb/* "${output_dir}"

View File

@@ -1,3 +1,21 @@
jellyfin (10.3.5-1) unstable; urgency=medium
* New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 09 Jun 2019 21:47:35 -0400
jellyfin (10.3.4-1) unstable; urgency=medium
* New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4
-- Jellyfin Packaging Team <packaging@jellyfin.org> Thu, 06 Jun 2019 22:45:31 -0400
jellyfin (10.3.3-1) unstable; urgency=medium
* New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3
-- Jellyfin Packaging Team <packaging@jellyfin.org> Fri, 17 May 2019 23:12:08 -0400
jellyfin (10.3.2-1) unstable; urgency=medium
* New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2

View File

@@ -18,3 +18,4 @@ rpmbuild -bb SPECS/jellyfin.spec --define "_sourcedir ${SOURCE_DIR}/SOURCES/pkg-
# Move the artifacts out
mkdir -p ${ARTIFACT_DIR}/rpm
mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/rpm/
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}

View File

@@ -23,13 +23,12 @@ fi
./create_tarball.sh
# Prepare temporary package dir
mkdir -p "${package_temporary_dir}"
# Set up the build environment Docker image
${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile
# Build the RPMs and copy out to ${package_temporary_dir}
${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}"
# Correct ownership on the RPMs (as current user, then as root if that fails)
chown -R "${current_user}" "${package_temporary_dir}" \
|| sudo chown -R "${current_user}" "${package_temporary_dir}"
# Move the RPMs to the output directory
mkdir -p "${output_dir}"
mv "${package_temporary_dir}"/rpm/* "${output_dir}"

View File

@@ -7,7 +7,7 @@
%endif
Name: jellyfin
Version: 10.3.2
Version: 10.3.5
Release: 1%{?dist}
Summary: The Free Software Media Browser
License: GPLv2
@@ -140,6 +140,12 @@ fi
%systemd_postun_with_restart jellyfin.service
%changelog
* Sun Jun 09 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5
* Thu Jun 06 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4
* Fri May 17 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3
* Tue Apr 30 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2
* Sat Apr 20 2019 Jellyfin Packaging Team <packaging@jellyfin.org>

View File

@@ -18,3 +18,4 @@ dpkg-buildpackage -us -uc -aarm64
# Move the artifacts out
mkdir -p ${ARTIFACT_DIR}/deb
mv /jellyfin_* ${ARTIFACT_DIR}/deb/
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}

View File

@@ -30,13 +30,12 @@ case $ARCH in
;;
esac
# Prepare temporary package dir
mkdir -p "${package_temporary_dir}"
# Set up the build environment Docker image
${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE}
# Build the DEBs and copy out to ${package_temporary_dir}
${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}"
# Correct ownership on the DEBs (as current user, then as root if that fails)
chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null \
|| sudo chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null
# Move the DEBs to the output directory
mkdir -p "${output_dir}"
mv "${package_temporary_dir}"/deb/* "${output_dir}"

View File

@@ -18,3 +18,4 @@ dpkg-buildpackage -us -uc -aarmhf
# Move the artifacts out
mkdir -p ${ARTIFACT_DIR}/deb
mv /jellyfin_* ${ARTIFACT_DIR}/deb/
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}

View File

@@ -30,13 +30,12 @@ case $ARCH in
;;
esac
# Prepare temporary package dir
mkdir -p "${package_temporary_dir}"
# Set up the build environment Docker image
${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE}
# Build the DEBs and copy out to ${package_temporary_dir}
${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}"
# Correct ownership on the DEBs (as current user, then as root if that fails)
chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null \
|| sudo chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null
# Move the DEBs to the output directory
mkdir -p "${output_dir}"
mv "${package_temporary_dir}"/deb/* "${output_dir}"

View File

@@ -17,3 +17,4 @@ dpkg-buildpackage -us -uc
# Move the artifacts out
mkdir -p ${ARTIFACT_DIR}/deb
mv /jellyfin_* ${ARTIFACT_DIR}/deb/
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}

View File

@@ -19,13 +19,12 @@ else
docker_sudo=""
fi
# Prepare temporary package dir
mkdir -p "${package_temporary_dir}"
# Set up the build environment Docker image
${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile
# Build the DEBs and copy out to ${package_temporary_dir}
${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}"
# Correct ownership on the DEBs (as current user, then as root if that fails)
chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null \
|| sudo chown -R "${current_user}" "${package_temporary_dir}" &>/dev/null
# Move the DEBs to the output directory
mkdir -p "${output_dir}"
mv "${package_temporary_dir}"/deb/* "${output_dir}"